当把基类转为派生类时,dynamic_cast失败。

问题描述 投票:0回答:1

我有两个类,基类和派生类,基类有一个虚拟方法。

这是我的测试例子。

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() 的方法后派生的类的 mBasemDerived.

但问题是,当我试图使用 dynamic_cast 它将使应用程序崩溃,如果我不使用 reinterpret_castHello() 的方法 Base 类将被调用。

结果在这种情况下 dynamic_cast:

Segmentation fault (core dumped)

案件结果 dynamic_cast:

-> Hello Base
c++ polymorphism dynamic-cast reinterpret-cast
1个回答
3
投票

当把基类转为派生类时,dynamic_cast失败了

这就是应该发生的事情。当你动态地将一个指针投向一个动态类型不是被投类型的对象时,你会得到一个空指针作为结果。

在你的例子中,你间接地通过空指针并试图调用一个成员函数,结果导致了未定义的行为。

当使用动态转码时,你必须始终检查你是否得到了null。

如果我使用reinterpret_cast...

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

例如,你可以像这样将一个基类实例转换为派生类。

Base b;
Derived d = b;

会发生的情况是,派生实例的基础子对象被复制初始化为 b.


0
投票

你的代码中有两个问题。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;
}
© www.soinside.com 2019 - 2024. All rights reserved.