在修复庞大代码库中的错误时,我观察到一种奇怪的情况,引用的动态类型从原始Derived
类型更改为Base
类型!我提供了最少的代码来解释这个问题:
struct Base {
// some 'virtual' function
protected: // copy constructor
private: // assignment operator
};
struct Derived : Base {
... // There are few more classes between `Base` and `Derived`
... // but for simplicity, I have put direct relation
};
void foo (Base &ref)
{
SomeClass obj;
obj.pVoid = &ref; // pVoid is of void*
// ----> typeid(ref) = Derived
(*funcptr)(obj);
// ----> typeid(ref) = Base !!!
Derived *p = dynamic_cast<Derived*>(&ref); // this fails ... i.e. "p = 0"
}
funcptr
是一个函数指针 ( void (*)(SomeClass&)
)。 funcptr
可以指向这么多的函数,并且它们有自己的调用流程,因此很难调试。
很奇怪,在调用函数指针后,派生类型ref
从Derived
变为Base
。为了简化我的工作,我怀疑对象切片 from Derived
to Base
,所以我将其制作~Base()
为纯virtual
并重新编译了整个源代码。但是没有编译器错误,这意味着没有Base
被声明的对象。
ref
Derived
动态类型更改为Base
以后dynamic_cast
失败的潜在原因是什么?