dynamic_cast在某些上下文中,从虚拟基础“base_class”到“derived_class”可能会失败
注解
默认情况下,此警告处于关闭状态。 有关详细信息,请参阅 Compiler Warnings That Are Off by Default。
在以下情况下会使用dynamic_cast操作:
- 转换是从基类指针到派生类的指针。
- 派生类虚拟继承基类。
- 派生类没有针对虚拟基类的
vtordisp字段。 - 强制转换位于派生类的构造函数或析构函数中,或位于继承自派生类的其他类中。 否则,将发出编译器警告 C4436,而不是 C4435。
此警告指示 dynamic_cast 在应用于部分构造的对象时可能无法正确执行。 当从从 derived_class继承的类的构造函数或析构函数调用封闭函数时,会出现这种情况。 如果 derived_class 从未进一步派生,或者在对象构造或销毁期间未调用封闭函数,则可以忽略此错误。
示例
以下示例生成 C4437,并演示缺少 vtordisp 字段产生的代码生成问题:
// C4437.cpp
// To see the warning and runtime assert, compile with: /W4
// To eliminate the warning and assert, compile with: /W4 /vd2
// or compile with: /W4 /DFIX
#pragma warning(default : 4437)
#include <cassert>
struct A
{
public:
virtual ~A() {}
};
#if defined(FIX)
#pragma vtordisp(push, 2)
#endif
struct B : virtual A
{
B()
{
func();
}
void func()
{
A* a = static_cast<A*>(this);
B* b = dynamic_cast<B*>(a); // C4437
assert(this == b); // assert unless compiled with /vd2
}
};
#if defined(FIX)
#pragma vtordisp(pop)
#endif
struct C : B
{
int i;
};
int main()
{
C c;
}