2012-10-07 64 views
3

我的要求與在stackoverflow上詢問Using Iterators to hide internal container and achieve generic operation over a base container [1]的問題相同。我有一個通用的純虛擬基礎容器類,它需要提供一個應該是STL投訴的迭代器,所以我可以使用它們與cpp算法的#include <algorithm>。我的實現只使用一個類而不是兩個類,如[1]解決方案。cpp迭代器繼承

基地純虛類

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; } 
}; 

我的執行工作是需要的,我想知道是否有與此實施方案的任何缺點,請幫我決定我的設計使用適當的實現。我有加我的全部工作示例代碼在github上:要點https://gist.github.com/3847688

編號:

回答

5

中最突出的問題:你的迭代器不具有值語義集成電路。

如果他們願意,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_ ?.因爲我們可以在沒有抽象類的實例的情況下初始化包裝器,如果可以的話如何防止它。我們可以使用'std :: unique_ptr'而不是虛擬'clone'。 – Kam

+2

「*如果你的迭代器以虛擬方法結束,你就錯了。*」如果可以的話,我會不止一次地使用這個+1。 – ildjarn

+1

@Kam:'std :: unique_ptr'處理所有權,'clone'處理複製。你可以同時使用兩者。 –