3

私の要件は、イテレーターを使用して内部コンテナーを非表示にし、スタックオーバーフローでベースコンテナー[ 1 ]に対する一般的な操作を実現するという質問と同じです。私は汎用の純粋な仮想ベース コンテナー クラスを持っています。これは、STL 準拠である必要があるイテレーターを提供する必要があるため、cpp アルゴリズムで使用できます#include <algorithm>私の実装では、[ 1 ] ソリューションのように 2 つのクラスではなく、1 つのクラスのみを使用します。

基本純粋仮想クラス

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:gist https://gist.github.com/3847688に完全に機能するサンプル コードを追加しました。

参照:

4

1 に答える 1

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メソッドを介してコピーを正しく管理するようにする必要があります。イテレータが仮想メソッドで終わる場合、それは間違っています。

于 2012-10-07T11:04:07.240 に答える