10

独自のコンテナを作成するタスクがLinked_listありArray_listます。私はそれらのための1つのインターフェースを持っています:

typedef int value_type;
class Container 
{
public:
        class Iterator 
        {   
        public:
            Iterator();
            Iterator(value_type* other);
            Iterator(const Iterator& other);
            Iterator& operator=(const Iterator& other);
                    ...
        };

    Container();
    Container(const Container& other);
    ~Container();   

    virtual value_type& front() const=0;
    virtual value_type& back() const=0;
    virtual Iterator begin() const=0; // 
    ...
};

Linked_listとArray_listの派生クラスを作成しました。

class Linked_list:public Container 
{
public:
    long int cur_size;
    List elem;
    static Link end_;
    class Iterator: public Container::Iterator
    {
        friend Linked_list;
        Link *p;    
    };

    Iterator begin() const; //overriding virtual function return type differs ...

...
}

私はそれがすべて間違っていると思います。ネストされたクラスLinked_list::Iteratorは派生クラスである必要がありますか?インターフェイスを変更できない場合、これを行うことはできますか?

4

2 に答える 2

9

テンプレートを使用できないという設計上の制約を考慮に入れると、変更する必要があるのは、インターフェイスの追加IteratorImplです。class Iteratorしたがって、ベースからclass Container 非仮想を作成できます。STLに似たイテレータは値のセマンティクスを持つ必要があるため、非仮想である必要があります。それがどのように機能するかの詳細については、pimplイディオムを参照してください!

このような:

typedef int value_type;
class Container 
{
    protected:
        class IteratorImpl
        {   
        public:
            virtual void next() = 0;
            virtual IteratorImpl* clone() const = 0;
            virtual value_type get() const = 0;
            virtual bool isEqual(const IteratorImpl& other) const = 0;
        };

    public:
        class Iterator 
        {   
        public:
            Iterator(IteratorImpl* impl) : impl(impl) {}
            ~Iterator() { delete impl; }
            Iterator(const Iterator& other) : impl(other.impl->clone()) {}
            Iterator& operator=(const Iterator& other) {
              IteratorImpl* oldImpl = impl;
              impl = other.impl->clone();
              delete oldImpl;
            }
            bool operator == (const Iterator& other) const 
            {
               return impl->isEqual(*other->impl);
            }
            Iterator& operator ++ ()
            {
                impl->next();
                return *this;
            }
            value_type& operator*() const 
            {
               return impl->get();
            }
            value_type* operator->() const
            {
               return &impl->get();
            }
        };
        Container();
        Container(const Container& other);
        ~Container();   

    virtual value_type& front() const=0;
    virtual value_type& back() const=0;
    virtual Iterator begin() const=0; // 
    ...
    };

次に、派生したものにIteratorImplを実装します。

class Linked_list:public Container 
{
protected:
    class IteratorImpl: public Container::IteratorImpl
    {
       ....
    };

public:
    Iterator begin() const { return new IteratorImpl(firstNode); }
    Iterator end() const { return new IteratorImpl(nodeAfterLastNode); }

...
};

これらのfirstNodeとnodeAfterLastNodeは私の推測です-IteratorImplインターフェースを実装するために必要なものは何でも使用してください...

于 2012-11-09T09:11:42.577 に答える
0

const value_type を表す const_value_type を定義し、それを front および back 仮想メソッドの戻り値に使用する必要があります。const メソッドに非 const 参照の戻り値の型を持たせることは意味がないため、代わりに、これらのメソッドに const 修飾子をドロップすることもできます。

クラスの詳細がなければ、残りの部分についてはわかりません。また、STL の初期の実装を見ることもできます。これは、これらのトピックについて洞察を得るのに非常に良い方法です。

于 2012-11-09T09:26:38.153 に答える