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,前提是静态已知类至少有一个virtual成员函数,或者如标准所述,前提是静态已知类是polymorphic

然而,在第三只手上,使用公共基类中的虚函数代替了类似 Java 的向下转换。通常直接具有这样的功能是可行的。对于更复杂的场景,您可能必须使用访问者模式(google it),但基本上,虚函数是实现向下转换效果的“安全”语言支持的类型安全方式。

于 2012-12-19T05:23:06.867 回答
2

您不能将它们弹出到它们的原始类中,当您将子类分配给超类的实例时,它会被分割成超类的实例。即c1c2其中的副本stack是现在的实例,Object而不是它们的原始类

类似于How can I make the method of child is called: virtual keyword not working?

于 2012-12-19T05:22:02.990 回答
2

即使您似乎在类中存储了派生类对象,但存储的只是对象的基类部分。简而言之,您会得到Object Slicing

总而言之,您不能将派生类对象存储在此容器中。您需要将指向 Base 的指针存储为容器类型,并使用动态多态性来实现这一点。

好读:
什么是对象切片?

于 2012-12-19T05:23:31.930 回答