3

次のコードは、出力します

Derived
Base
Base

しかし、すべてのDerivedオブジェクトをUser :: itemsに入れて、独自のprint関数を呼び出す必要がありますが、基本クラスのオブジェクトは必要ありません。ポインターを使用せずにそれを達成できますか?それが不可能な場合、メモリリークが発生しないように、User :: itemsを1つずつ削除してメモリを解放する関数を作成するにはどうすればよいですか?

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Base{
public:
  virtual void print(){ cout << "Base" << endl;}
};

class Derived: public Base{
public:
  void print(){ cout << "Derived" << endl;}
};

class User{
public:
  vector<Base> items;
  void add_item( Base& item ){
    item.print();
    items.push_back( item );
    items.back().print();
  }
};

void fill_items( User& u ){
  Derived d;
  u.add_item( d );
}

int main(){
  User u;
  fill_items( u );
  u.items[0].print();
}
4

3 に答える 3

5

ポインタを使用する必要があり、基本クラスに仮想デストラクタを与える必要があります。デストラクタは何もする必要はありませんが、存在している必要があります。追加関数は次のようになります。

void add_item( Base * item ){
    item->print();
    items.push_back( item );
}

ここで、itemsはvector<Base *>です。アイテムを破棄するには(仮想デストラクタを想定):

for( int i = 0; i < items.size(); i++ ) {
    delete items[i];
}
items.clear();
于 2010-04-04T17:44:52.447 に答える
1

Derivedtypeのポインターで delete を呼び出すときに、 type のオブジェクトが適切に破棄されるようにするには、 base の仮想デストラクタが必要ですBase

class Base{
public:
  virtual void print(){ cout << "Base" << endl;}

  virtual ~Base( ) { }  // virtual destructor
};

次に、Boosts ptr_vectorを使用して、コンテナーが破棄されたときに削除されるオブジェクトへのポインターを格納できます。

于 2010-04-04T17:48:29.567 に答える
0

説明するだけです:

何が起こっているのかを理解するために、クラス Base 抽象を定義してみてください (たとえば、純粋な仮想メソッドを定義します)。この場合、コンパイラ エラーが表示されると思います。このようにして、vector が実際に何をするかを認識できます。push_back( generated ) を実行すると、コピー構築によってクラス Base の新しいインスタンスが作成されます。これが、代わりにポインターを使用する理由です。次に、ベクターは、タイプ Base の独自のコピーではなく、タイプ Derived の最初に作成されたオブジェクトで機能します。

于 2010-04-08T08:44:17.150 に答える