1

私がやりたいことは、リストがあることですstd::list<Displayable> display_queue

Displayable は次のように定義されDisplayable.hています。

class Displayable { 

    public:

        int x, y;

        Displayable() : x(0), y(0) {}
        Displayable(int x, int y) : x(x), y(y) {}

};

そしてDifferentDisplayable次のように:

class DifferentDisplayable : public Displayable { 

    public:

        std::string id;

        DifferentDisplayable() : Displayable(), id("") {}
        DifferentDisplayable(int x, int y) : Displayable(x, y), id("") {}
        DifferentDisplayable(int x, int y, std::string id) : Displayable(x, y), id(id) {} 

};

リストに追加された項目は次のとおりです。

Displayable disp_one;
DifferentDisplayable disp_two(10, 10, "the id");

display_queue.push_back(disp);
display_queue.push_back(disp_two);

からDifferentDisplayable派生しDisplayableているため、リストに格納できますが、次のようにリスト (display_queue) を反復処理するときに、std::string idどのようにアクセスできるか、またはアクセスできるかはわかりません。DifferentDisplayable

for (std::list<Displayable>::iterator i = display_queue.begin(); i != display_queue.end(); i++) {

    // insert code here

}

ご回答ありがとうございます。

4

2 に答える 2

1

すべての派生クラスで 'id' が必要ない場合は、ループから直接アクセスしようとする代わりに、それを使用する基本クラス メソッドを追加します。例えば:

class Displayable
{
public:
  virtual void Display();
  ...
};

(「class Displayable」を抽象基本クラスにし、Display() を純粋な仮想関数として使用することをお勧めします。以下のリンクを参照してください。)

次に、実装は個別に異なる場合があります。

void Displayable::Display()
{
  // Do something here with 'x' and 'y'
}

void DifferentDisplayable::Display()
{
  // Do something here with 'x', 'y', and 'id'
}

次に、オブジェクトをヒープに割り当てて、スライスの問題を回避します。

Displayable* disp_one = new Displayable();
DifferentDisplayable* disp_two = new DifferentDisplayable(10, 10, "the id");

display_queue.push_back(disp);
display_queue.push_back(disp_two);

次に、ループは次のようになります。

for (std::list<Displayable>::iterator i = display_queue.begin(); i != display_queue.end(); ++i) {
  (*i)->Display();
}

使い終わったら、ポインタを「削除」することを忘れないでください。

この戦略については、Open-Closed Principleと、 Scott Meyers による『Effective C++ 3rd Edition』の項目 34「インターフェイスの継承と実装の継承を区別する」で説明されています。

于 2013-09-18T18:11:05.230 に答える