为简单起见,
class Parent {}
class Child1 : Parent {}
class Child2 : Parent {}
在其他地方,我创建了Child1和Child2的实例,并将其存储在Parent:
下的相同向量中// . . . in .h file, for example
vector<Parent> vector_of_parent;
// . . . in one particular method
Child1 c1;
Child2 c2;
vector_of_parent.push_back(c1);
vector_of_parent.push_back(c2);
// . . .
然后在另一种有权访问vector_of_parent
的方法中,我尝试了
void doSomething(Parent& some_child) {
// wrapped in a try block somehow...
Child1& c = dynamic_cast<Child1&> some_child;
// do something if the cast is successful
}
void otherMethod() {
doSomething(vector_of_parent.at(0)); // vector_of_parent.at(0) is a Child1
}
为什么在调用otherMethod()时会出现std:bad_cast?
答案 0 :(得分:7)
您的std::vector
被声明为std::vector<Parent>
。它仅包含Parent
的实例 - 当您插入Child1
和Child2
个实例时,它们会获得sliced。
如果要使用具有公共基类Parent
的多态对象向量,则需要使用指针容器(或者,为了便于生命和内存管理,使用智能指针)。
要考虑的适当容器类型包括std::vector<Parent*>
,std::vector<std::tr1::shared_ptr<Parent> >
和boost::ptr_vector<Parent>
。
除非您对手动内存管理非常熟悉,否则我建议不要使用std::vector<Parent*>
。
此外,您需要使用公共继承而不是私有,并且基类必须具有虚拟析构函数。我假设你为了简洁而把它们留下了。
答案 1 :(得分:6)
当你说:
vector<Parent> vector_of_parent;
您创建了父矢量 - 它不可能包含Child对象。如果你想要一个多态C ++容器,它必须包含基类指针。你的动态演员表失败了,因为你应用它的东西总是Parent而不是Child。
此外,您的代码并不清楚,但为了使用dynamic_cast,您的基类必须至少包含一个虚函数。
答案 2 :(得分:3)
vector<Parent> vector_of_parent;
您正在创建Parent
个对象的向量。请注意,vector将始终创建传递的对象的副本。因此,当您执行vector_of_parent.push_back(c1);
时,会创建一个c1副本,其代码类似于(为简单起见,我忽略了分配器)T* pObj = new T(c1);
。由于此处的T类型为Parent
,因此创建的副本的类型为Parent
。所以基本上是什么,子对象被切片以创建父对象。现在,如果您尝试将此Parent
对象动态广播为Child
类型,则会抛出异常。