我有一个基类和一个派生类.每个类都有一个.h文件和一个.cpp文件.
我在以下代码中对派生类执行基类对象的dynamic_cast:
h文件:
class Base { public: Base(); virtual ~Base(); }; class Derived : public Base { public: Derived(){}; void foo(); }; class Another { public: Another(){}; void bar(Base* pointerToBaseObject); };
cpp文件:
Base::Base() { //do something.... } Base::~Base() { //do something.... } void Derived::foo() { Another a; a.bar(this); } void Another::bar(Base* pointerToBaseObject) { dynamic_cast(pointerToBaseObject) }
从某些奇怪的原因,转换失败(返回NULL).但是,如果我将Derived类的构造函数的实现从.h移动到.cpp文件,则转换成功.
什么可以导致它?
编译器是Linux-SUSE上的gcc 3.1.顺便说一句,我只在这个平台上看到这种行为,并且相同的代码在Visual Studio中运行良好.
你在Base有任何虚拟功能吗?否则它将不起作用.如果没有别的,让它的dtor虚拟.
不知道是否已经被其他人要求删除了他的答案,但我相信它有所不同:你是否正在从基地的构造函数中进行dynamic_cast?如果是这样,那将无效.编译器会认为Base是派生类型最多的类型,类似于调用虚函数时它最终调用Base的版本.
如果你在基类中有一个虚函数(如litb指出的那样),那么发布的代码不应该失败.
但是我相信当前的每个编译器都会生成一个"基类不是多态的"错误,如果你没有,那么这可能不会是问题.
我唯一能想到的是,由于一些奇怪的bug,所有内容都被内联,并且没有生成vtable.但是如果你把构造函数放在C++文件中,编译器决定不内联所有内容,触发创建vtable,导致你的强制转换工作.
但这是非常疯狂的猜测,我认为任何编译器都不会有这样的错误(?)
如果您想要一个明确的答案,请发布更多代码.并使用编译器/平台.
编辑:看到更新的代码
我认为你至少应该派生出来自Base;)(我想这是一个错字)
但在看到代码后,我唯一能想到的是gcc(错误地)内联所有内容并且不会为Derived生成vtable.对于它的价值,这运行良好编译与gcc 4.0
3.1现在已经超过7岁......如果有任何升级的可能性,我会去追求它.