dynamic_cast 将基础 class 转换为派生 class 时失败

dynamic_cast fails when cast a base class to derived class

我有两个 classes,基础 class 和派生的 class。 基础 class 有一个虚拟方法。

这是我的测试示例:

class Base
{
public:
    virtual void Hello() { cout << "-> Hello Base" << endl; }
};

class Derived: public Base
{
public:
    void Hello() { cout << "-> Hello Derived" << endl; }
};

int main()
{
    Base *mBase = new Base;
    // something to do 
    ....

    Derived *mDerived = dynamic_cast<Derived*>(mBase);
    mDerived->Hello();

    return 0;
}

我正在寻找使用 Hello() 的方法 class 在将 mBase 转换为 mDerived 之后派生的方法。

但问题是,当我尝试使用 dynamic_cast 时,如果我使用 reinterpret_cast BaseHello() 方法,它会使应用程序崩溃class 会被调用。

案例dynamic_cast的结果:

Segmentation fault (core dumped)

案例dynamic_cast的结果:

-> Hello Base

dynamic_cast fails when cast a base class to derived class

这是应该发生的事情。当您将指针动态转换为动态类型不是转换类型的对象时,您会得到一个空指针。

在您的示例中,您间接通过空指针并尝试调用导致未定义行为的成员函数。

使用动态转换时,必须始终检查是否为 null。

if I use reinterpret_cast...

那么行为仍将是未定义的,因为您将通过指向不存在的对象的指针进行间接访问。除非创建派生的实例 class,否则不能调用其非静态成员函数。

您可以将基本实例转换为派生实例,例如:

Base b;
Derived d = b;

派生实例的基础子对象是从b复制初始化的。

您的代码中有两个问题:Base 应该有一个虚拟析构函数,这样 Dervied 实例可以通过指向 Base 的指针正确销毁。那么,您不是在构造 Derived 类型的对象,因此转换不会成功。 dynamic_cast 可能会失败,您应该检查其结果是否为 nullptr。还有你忘记删除创建的对象了。

如果您确实创建了一个 Derived 类型的实例,您的代码有效:

#include <iostream>
using std::cout;
using std::endl;

class Base
{
public:
    virtual void Hello() { cout << "-> Hello Base" << endl; }
    virtual ~Base(){}
};

class Derived: public Base
{
public:
    void Hello() { cout << "-> Hello Derived" << endl; }
};

int main()
{
    Base* mBase = new Derived;
    Derived *mDerived = dynamic_cast<Derived*>(mBase);
    if (mDerived) mDerived->Hello();
    delete mBase;
}