2012-10-07 3 views
3

내 요구 사항은 질문과 동일합니다 Using Iterators to hide internal container and achieve generic operation over a base container [1] at stackoverflow. 나는 일반적인 순수 가상베이스 컨테이너 클래스를 가지고있다. 그래서 나는 cpp 알고리즘의 #include <algorithm>과 함께 사용할 수있는 STL 불평이 있어야하는 반복자를 제공해야한다. 내 구현에서는 [1] 솔루션 에서처럼 두 클래스 대신 하나의 클래스 만 사용합니다.cpp iterator 상속

자료 순수 가상 클래스

class BaseItr 
{ 
    public: 
    class iterator : public std::iterator<std::input_iterator_tag, int> 
    { 
     public: 
     iterator() : _in(NULL) {} 
     inline iterator(const iterator& org) : _in(org._in) {} 
     inline iterator& operator=(const iterator& other) { _in = other._in; return *this; } 
     virtual inline int operator *() { return _in->operator*(); } 
     virtual inline iterator& operator++() { (*_in)++; return *this; } 
     virtual inline iterator& operator++(int unused) { (*_in)++; return *this; } 
     virtual inline bool operator==(const iterator& other) 
     { 
      return *(*_in) == *(*(other._in)); 
     } 
     virtual inline bool operator!=(const iterator& other) 
     { 
      return *(*_in) != *(*(other._in)); 
     } 
     // would use shared pointer insted of this 
     //~iterator() { if(_in) { delete _in; } } 
     static inline iterator New(iterator *in) { return iterator(in); } 
     private: 
     iterator(iterator *in) : _in(in) {} 
     iterator *_in; 
    }; 

    virtual iterator begin() = 0; 
    virtual iterator end() = 0; 
}; 

구현

class Itr : public BaseItr 
{ 
    private: 
    class iterator : public BaseItr::iterator 
    { 
     public: 
     iterator(int val) : _val(val), BaseItr::iterator() {} 
     int operator *() { return _val; } 
     inline iterator& operator++() { ++_val; return *this; } 
     inline iterator& operator++(int unused) { _val++; return *this; } 
     private: 
     int _val; 
    }; 
    BaseItr::iterator _begin; 
    BaseItr::iterator _end; 
    public: 
    inline Itr(int start, int end) 
    { 
     _begin = BaseItr::iterator::New(new iterator(start)); 
     _end = BaseItr::iterator::New(new iterator(end)); 
    } 

    BaseItr::iterator begin() { return _begin; } 
    BaseItr::iterator end() { return _end; } 
}; 
는 내 구현 작품, 내가이 구현 어떤 단점이있다 알고 싶어 필요했다

날에 결정 도와주세요 내 디자인은 적절한 구현을 사용합니다. 요점 https://gist.github.com/3847688

참조 :

답변

5

가장 눈부신 문제 : 나는 GitHub의에서 내 전체 작업 예제 코드를 추가하도록하여 반복자에는 값 semant가 없습니다. ics.

STL 알고리즘은 원하는 경우 반복자를 자유롭게 복사 할 수 있습니다.

template <typename It> 
It find(It b, It e, typename std::iterator_traits<It>::const_reference t) { 
    for (; b != e; ++b) { 
     if (*b == t) { return b; } 
    } 
    return e; 
} 

문제는 당신이 BaseItr&으로이 알고리즘을 호출 할 경우, 결과 유형 BaseItr의 것을, 당신은 이렇게 정의되지 않은 동작입니다 객체 슬라이스에 노출되어있다 : 예를 들어 가정합니다.

반복자에 가치 의미론을 부여하려면 추상 구현을 중심으로 래퍼 클래스를 만들고 래퍼가 가상 clone 메서드를 통해 사본을 올바르게 관리해야합니다. 반복자가 가상 ​​메서드로 끝나면 잘못하고 있습니다.

+0

반복자가 추상 구현의 래퍼 인 경우 _Object Splicing_?을 계속 사용하지 않아도됩니까? 우리가 추상 클래스의 인스턴스없이 래퍼를 초기화 할 수 있다면 그렇게하는 것이 좋습니다. 가상'clone '대신'std :: unique_ptr'을 사용할 수 있습니까? – Kam

+2

"* 반복자가 가상 ​​메소드로 끝나면 잘못하고있는 것입니다. *"할 수 있으면 이것을 한 번 이상 +1합니다. – ildjarn

+1

@Kam :'std :: unique_ptr'은 소유권을 다루고,'clone'은 복사를 다루고 있습니다. 함께 사용할 수 있습니다. –