0

多くの質問が寄せられていることは知っています。ググったのですが、すべてをまとめることができませんでした。できないからかな、何がしたいの?

私は持っている

struct Universe
{
}

struct Atom: Universe
{
}

struct Molecule: Universe
{
}

Universe U;
Atom A;
Molecule M;
_atoms =  vector<Universe*>(3);
_atoms.push_back(&U);
_atoms.push_back(dynamic_cast<Universe*>(&A));
_atoms.push_back(dynamic_cast<Universe*>(&M));

auto THIS_IS_ATOM = _atoms[1];

このコードは、多くの点で間違っている可能性があります。しかし、私の考えは、このようなさまざまな派生構造体を格納し、後でデータ損失やクラスの切り捨てを行うことなく、配列またはリストからそれらにアクセスすることでした。_atoms[1] のような配列からいくつかの要素を取得し、この構造体がどのタイプ (Universe または Atom) であるかなどを知ることができるようにしたかったのです。

C++で適切に行うにはどうすればよいですか?

4

1 に答える 1

0

あなたのコードにはいくつかの問題があります。

  1. ユニバースには仮想デストラクタが必要です。
  2. ヒープ上にインスタンスを作成する必要があります。
  3. 間違った std::vector コンストラクターを使用しています。

これがうまくいくはずの解決策です:

struct Universe {
    virtual ~Universe() {} // otherwise Atom and Molecule will not be deleted properly
}

struct Atom : Universe {

}

struct Molecule : Universe { 

}

std::vector<Universe*> _atoms; // you don't need to pass anything in the constructor
_atoms.reserve(3); // but if you want to make sure that the vector has exactly a capacity of 3, use this

_atoms.push_back(new Universe());
_atoms.push_back(new Atom());
_atoms.push_back(new Molecule());

auto this_is_atom = _atoms[1]; // will actually be equivalent to
Universe* this_is_atom = _atoms[1];

// finally you must delete all the instances which you created on the heap
while (!_atoms.empty()) delete _atoms.back(), _atoms.pop_back();

補遺: ベクター内のオブジェクトを非ポリモーフィックに処理する必要がある場合は、静的キャストを使用して適切な型にキャストできます。

Atom* a = static_cast<Atom*>(_atoms[1]);

編集:生のポインターのベクトルを使用する代わりに、モデル化しようとしている所有権のセマンティクスに応じて、代わりにスマート ポインターのベクトルを使用することをお勧めします。たとえば、std::unique_ptr または std::shared_ptr です。

于 2013-07-27T14:58:05.613 に答える