如果我有以下课程:
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
),因为我在这里不使用指针?
答案 0 :(得分:8)
简短的回答是,对于您的堆栈,您不能将元素作为派生类类型元素弹出。通过将它们放入堆栈,您可以切片它们到堆栈的元素类。也就是说,只有那个基类部分被复制到堆栈中。
然而,您可以拥有一堆指针,然后您可以使用dynamic_cast
,前提是静态已知的类至少有一个virtual
成员函数,或者标准所说,前提是静态已知类是多态。
然而,在第三个抓握的手上,而不是类似Java的向下转换在公共基类中使用虚函数。通常它只是直接具有这样的功能。对于更复杂的场景,您可能必须使用访问者模式(google it),但基本上,我们的想法是虚拟功能是“安全”语言支持的类型安全方式来实现向下转换的效果
答案 1 :(得分:2)
当您将子类分配给超类的实例时,它不能将它们弹出到原始类,它会将sliced转换为超类的实例。即c1
中c2
和stack
的副本现在是Object
的实例,而不是其原始类
与How can I make the method of child be called: virtual keyword not working?类似
答案 2 :(得分:2)
即使你在类中存储了一个派生类对象,但是存储的内容只是该对象的Base类部分。简而言之,你得到对象切片。
总而言之,您无法在此容器中存储派生类对象。您将需要存储指向Base的指针作为conainter的类型,并使用动态多态来实现此目的。