6

次のクラスがある場合:

class Object { ... } 

class MyClass1: public Object { ... } 

class MyClass2: public Object { ... }

とスタック:std::stack<Object> statesObjects;

MyClass1 c1;
MyClass2 c2;

statesObjects.push(c1); // okay
statesObjects.push(c2); // okay 

ここではポインターを使用しないため、それらをポップアウトして、スタックの先頭にある要素を ( を使用してtop()) なしで取得するにはどうすればよいですか?dynamic_cast

4

3 に答える 3

8

簡単に言えば、スタックをそのまま使用すると、要素を派生クラス型の要素としてポップアウトできないということです。それらをスタックに入れることで、それらをスタックの要素クラスにスライスしました。つまり、その基本クラスの部分だけがスタックにコピーされています。

ただし、ポインターのスタックを持つことはできますdynamic_cast。静的に既知のクラスに少なくとも 1 つのvirtualメンバー関数がある場合、または標準が言うように、静的に既知のクラスが多態的である場合に使用できます。

しかし、3 つ目の魅力的な方法は、Java のようなダウンキャストの代わりに、共通の基底クラスで仮想関数を使用することです。多くの場合、そのような機能を直接持つだけで機能します。より複雑なシナリオでは、ビジター パターン(google it)を使用する必要があるかもしれませんが、基本的には、仮想関数は、ダウンキャストの効果を達成するための「安全な」言語サポート型の安全な方法であるという考えです。

于 2012-12-19T05:23:06.867 に答える
2

それらを元のクラスにポップアウトすることはできません。サブクラスをスーパークラスのインスタンスに割り当てると、スーパークラスのインスタンスにスライスされます。c1つまり、とのコピーはc2stack現在は のインスタンスでObjectあり、元のクラスではありません

子のメソッドを呼び出すにはどうすればよいですか: 仮想キーワードが機能しない? に似ています。

于 2012-12-19T05:22:02.990 に答える
2

クラスに派生クラス オブジェクトを保存しているように見えても、保存されるのはオブジェクトの基本クラス部分だけです。要するに、Object Slicingを取得します。

要約すると、派生クラス オブジェクトをこのコンテナーに格納することはできません。Base へのポインターを conainter の型として格納し、これを実現するには動的ポリモーフィズムを使用する必要があります。

よく読んでください:
オブジェクトのスライスとは?

于 2012-12-19T05:23:31.930 に答える