1

A仮想メソッドを持つというクラスを作成しましたdo_something

class A {
  virtual int do_something() = 0;
}

BサブクラスA

class B {
  virtual int do_something() {
    return 42;
  }
}

私の主な機能のどこかで、これを行います。

vector<A> arr;
arr.push_back(B());
int val = arr[0].do_something();

do_somethingただし、純粋仮想関数であると文句を言うコンパイラエラーが発生します。これは、ベクトルが型のオブジェクトを含むように宣言したためでAありA、抽象クラスであると思います。したがって、コンパイラは、が定義されているBかどうかを確認するためにクラスを調べることを知りません。do_something

これを回避する方法はありますか?異なるタイプのオブジェクトのベクトルを保存できますか(共通の仮想関数を宣言しますが、共通のスーパークラスを使用します)?

4

2 に答える 2

4

このようにベクトルを宣言することにより:

vector<A> arr;

直接型 のオブジェクトのベクトルを作成しようとしていますABこれにより、タイプのオブジェクトをそこに格納できないだけでなく(A抽象的でない場合は、スライスが発生しますが、これは絶対に望ましくありません)、の直接インスタンスAが存在できないため、コンパイルに失敗します。

ここで必要なのは、 (おそらくスマートポインター)へのポインターを格納することです。A

#include <memory> // For smart pointer classes

vector<shared_ptr<A>> arr;
arr.push_back(make_shared<B>());
int val = arr[0]->do_something();

ここではshared_ptr、共有所有権を想定してを使用することにしましたが、オブジェクトの唯一の所有者がコンテナarrである場合はunique_ptr、より適切な選択になります。

最終的に、自分が何をしているのかを本当に理解していて、自動メモリ管理の煩わしさに耐える準備ができている場合は、生のポインタを使用できますが、そうすることはお勧めしません(delete割り当てるすべてのオブジェクトの割り当てを解除する必要があります)。とnew):

vector<A*> arr;
arr.push_back(new B());
int val = arr[0]->do_something();
于 2013-03-05T09:56:30.353 に答える
2

これを回避する方法はありますか?異なるタイプのオブジェクトのベクトルを保存できますか(共通の仮想関数を宣言しますが、共通のスーパークラスを使用します)?

std::vectorでスマートポインタを使用する

std::vector<std::unique<A>> arr;
arr.emplace_back(new B());

また

arr.emplace_back(std::make_shared<B>());
于 2013-03-05T09:55:46.577 に答える