#include <iostream>

#include <string>

using namespace std;

 

// 모든 반복자가 가져야 하는 인터페이스를 설계한다. - 실제 C#에는 아래의 interface가 있다.

 

// C# 1.0 에서는 Object 최상위클래스로 받아서 타입캐스팅을 했지만..

// C# 2.0 에서는 Generic의 도입으로 반복자 인터페이스가 편리해졌다.

template<typename T> struct IEnumerator

{

        virtual bool MoveNext() = 0;

        virtual T GetObject() = 0;

        virtual void Reset() = 0;

};

//-------------------------------------------------------

// 또한 반복자를 가질 수 있는 모든 컨테이너는 아래의 인터페이스를 제공해야 한다.

template<typename T> struct IEnumerable

{

        virtual IEnumerator<T>* GetEnumerator() = 0;

};

 

//-------------------------------------------------------

// 열거가능한(반복자를가진) 클래스는 반드시 IEnumerable에서 파생되어야 한다.

template<typename T> class slist : public IEnumerable<T>

{

        struct Node

        {

               T     data;

               Node* next;

 

               Node( T a, Node* n ) : data(a), next(n) {}

        };

 

        Node* head;

public:

        slist() : head(0) {}

 

        void push_back( T a ) { head = new Node( a, head ); }

 

        // slist에서 값을 얻기 위한 반복자

        class SlistEnumerator : public IEnumerator<T>

        {

               Node* current;

               Node* head;

        public:

               SlistEnumerator( Node* init = 0 ) 
               : head(init), current(init) {}

 

               bool MoveNext()

               {

                       current = current->next;

                       return current != 0;

               }

               int  GetObject() { return current->data; }

               void Reset() { current = head; }

        };

 

        //--------------------------------------------------

        // 반복자를 리턴하는 함수를 만든다.

        IEnumerator<T>* GetEnumerator()

        {

               return new SlistEnumerator( head );

        }

};

 

//------------------------------------------------------

// 주어진 반복자를 사용해서 모든 요소의 합을 구한다.

template<typename T> void Sum( IEnumerator<T>* p )

{

        T s = T();

 

        p->Reset();

 

        do

        {

               s += p->GetObject();

        } while ( p->MoveNext() );

 

        cout << s << endl;

}

// 주어진 컨테이너의 모든 요소의 합을 구한다.

template<typename T> void Sum2( IEnumerable<T>& c )

{

        IEnumerator<T>* p = c.GetEnumerator();

        Sum( p );

}

 

int main()

{

        slist<int> s;

 

        s.push_back( 10 );

        s.push_back( 20 );

        s.push_back( 30 );

 

        //IEnumerator<int>* p = s.GetEnumerator();

        //Sum( p );

 

        Sum2( s );

 

        return 0;

}

 

 

Tag |

Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다