0

実際の C++ アプリケーションで反復子を実装することは、控えめに言ってもかなり混乱するようです。イテレータを理解するためにデモでこれを実装しています。

私は AudoDealer クラスを持っています。これには住所などがあり、そのディーラーのすべての車を含む実際のリスト (私の場合は stl::list) があります。ここで、そのディーラーのすべての車を反復処理できる反復子が必要です。

最初の質問は、concrete-iterator がクラスまたは車を格納するこのクラス内AutoDealerの実際のものを取得する必要があることです。listAutoDealer クラスを取り入れたいのですが、そのようにして、クラスの所有権を取得し、構造の内部部分のみにポーズをとっている独立したイテレータとは対照的に、すべてをまとめて処理しますが、後でより良いように見えますか?

2 番目の質問は、STL リスト クラスをコンテナーとして使用しているため、保存int currentItemは意味がありませんがstd::list<>iterator、トラバースするために保存する必要があるということです。そもそも、このイテレータ型を格納することはできません! これは、リストの実装を公開するという原則を破ります。

私のコードは以下にあり、まだ進行中ですが、すべてが以下にあり、ところで私は4冊の本のギャングに従っています。

// IteratorDemo.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <list>

using namespace std;

template <class Object>
class Iterator
{
public:
    virtual Object * first();
    virtual Object * next();
    virtual bool IsDone() const  = 0;
    virtual Object * currentItem() const  = 0;
};


class Car
{
    string make;
    string model;
    string price;
    bool isTruck; // if true is truck, otherwise sedan (assume for this example)
};

//template <class Item>
class AutoDealer
{
public:
    AutoDealer();
    virtual ~AutoDealer();

    // create iterator
    //virtual Iterator<item> * CreateIterator() = 0;



    virtual string GetDealerAddress() 
    { 
        return address;
    };
    virtual void SetDealerAddress(string addr)
    {
        address = addr;
    }
    virtual void SetNumberOfSedans() = 0;
    virtual void SetNumberOfTrucks() = 0;

    virtual Car * GetCar() = 0;
    virtual void AddCar(Car car) = 0;

protected:
    string address;

};

//template <class item>
class AutoDealerImpl : public AutoDealer
{
public:
    AutoDealerImpl()
    {
    }
    virtual ~AutoDealerImpl();

/*  virtual Iterator<item> * CreateIterator()
    {
        return std::list<Car>::iterator;
    }
*/

    virtual void SetNumberOfSedans();
    virtual void SetNumberOfTrucks();

    virtual Car * GetCar();
    virtual void AddCar(Car car)
    {
        carList.push_back( car );
    }

protected:
    std::list<Car> carList; // list implementation


};

template <class Object>
class AutoDealerIterator : public Iterator<Object>
{
public:
    AutoDealerIterator( AutoDealer * theDealer )
    {
//      dealer = theDealer;
    }
    virtual Object * first()
    {
    }
    virtual Object * next();
    virtual bool IsDone() const  = 0;
    virtual Object * currentItem() const  = 0;

protected:
    AutoDealer * dealer;
    int _currentItem; // this is an issue, it should be std::list<car>::iterator type here but how can I access that?
                     // I am not traversing a simple list but an STL list which already
                    // has its own iterator and I need that iterator to travese but how do I access it?

};


int _tmain(int argc, _TCHAR* argv[])
{



}

アップデート

このデモ プロジェクトには、前の質問を回避できる別の目標があります。私が持っているように、CAutoDealerどちらが単なるインターフェースであり、AutoDealerImplどちらが具体的です。データ メンバーは、実際にはカプセル化のためにコンクリート内に存在します。インターフェイス クラスを使用してデータを反復処理するにはどうすればよいですか?

私の主な目的は、アプリケーションを反復処理するstd::list<Car>ことです。この責任を負うべきかAutoDealer、メイン クラスの外側でこれを反復することは OOP に準拠していますか? 私の目標は、優れたオブジェクト指向設計であり、設計パターンを受け入れることです。

4

1 に答える 1

1

実行時のポリモーフィック イテレータを使用することを主張する場合は、具象イテレータにコンストラクタでstd::list<Car>::iterators のペアを取得させ、それらを構築できるように、privateあなたAutoDealerImplの友人を作成します。AutoDealerIterator

class AutoDealerIterator
    : public Iterator<Car>
{
    friend class AutoDealer;
    std::list<Car>::iterator d_begin;
    std::list<Car>::iterator d_it;
    std::list<Car>::iterator d_end;

    AutoDealerIterator(std::list<Car>::iterator begin, std::list<Car>::end)
        : d_begin(begin)
        , d_it(begin)
        , d_end(end)
    {
    }
public:
    Car * first() final { this->d_it = this->d_begin; return this->next(); }
    Car * next() final  { return ++this->d_it == this->d_end? 0: &*this->d_it; }
    bool  IsDone() const final { return this->d_it == this->d_end; }
    Object * currentItem() const final { return &*this->d_it; }
};

から実際のAutoDealerIteratorオブジェクトを作成するのAutoDealerは簡単です。

実行時のポリモーフィック イテレータを使用することは、一般的に悪い考えであることに注意してください。これは、まったく機能せず、比較的遅くなる可能性が非常に高いです。さらに、シーケンスのほとんどの処理は、実際には処理対象のオブジェクトの具体的なアイデアを持っているようです。

于 2013-09-19T22:43:53.427 に答える