编译器警告(级别 1 和级别 4,关闭) C4437

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;
}

另请参阅

dynamic_cast 运算符
vtordisp
编译器警告(等级 1)C4436