3

私は次の2つのクラスを持っています、1つは他から継承します

Class A{
  void print(){cout << "A" << endl;}
}

Class B : A{
  void print(){cout << "B" << endl;}
}
Class C : A{
  void print(){cout << "C" << endl;}
}

次に、別のクラスで次のようになります。

vector<A> things;
if (..)
  things.push_back(C());
else if (..)
 things.push_back(B());

things[0].print();

これは常にA
を出力します。ベクトルに追加したものに応じてBまたはCを出力したいのですが、
どうすればよいですか?
抽象化を試しましたが、C ++での使用方法が完全にはわかりません。また、抽象化が機能していません。

4

3 に答える 3

8

1)クラスAでprint()を仮想として宣言する必要があります。

2)ベクトルが正しくありません。実際のクラスAオブジェクトをそこに格納することはできません。正しい動作のためにそれらへのポインタを保存する必要があり(そして後でそれらをクリーンアップする必要があります)、および/またはboost::shared_ptrのようなものを使用する必要があります。

于 2010-03-06T00:47:32.427 に答える
8

前述のように、virtualポリモーフィックな動作を有効にする関数が必要であり、クラスを値によって直接vector.

を使用するstd::vector<A>と、値によって格納されるため、たとえば経由で追加したオブジェクトはpush_back()のインスタンスにコピーされます。つまり、オブジェクトの派生部分がA失われます。この問題は、オブジェクトのスライスとして知られています。

すでに示唆されているように、ポインター (またはスマート ポインター) を基底クラスに格納することで回避できるため、ポインターのみが にコピーされvectorます。

std::vector<A*> things;
things.push_back(new B());
// ... use things:
things[0]->print();

// clean up later if you don't use smart pointers:
for(std::vector<A*>::iterator it = things.begin(); it != things.end(); ++it)
    delete *it;
于 2010-03-06T01:05:00.013 に答える
3

基本クラス(この場合はクラスa)で関数virtualを宣言する必要があります。

class A{
  virtual void print(){cout << "A" << endl;}
}

他のクラスは、仮想を記述していなくてもこれを取得します(ただし、可能です)。

Virtualは、関数がオーバーライドされる可能性があることをコンパイラーに通知します。仮想を使用しない場合、それは非表示と呼ばれ、ご存知のように動作が異なります。

于 2010-03-06T00:47:03.007 に答える