我有两个类,基类和派生类,基类有一个虚拟方法。
这是我的测试例子。
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()
的方法后派生的类的 mBase
到 mDerived
.
但问题是,当我试图使用 dynamic_cast
它将使应用程序崩溃,如果我不使用 reinterpret_cast
的 Hello()
的方法 Base
类将被调用。
结果在这种情况下 dynamic_cast
:
Segmentation fault (core dumped)
案件结果 dynamic_cast
:
-> Hello Base
当把基类转为派生类时,dynamic_cast失败了
这就是应该发生的事情。当你动态地将一个指针投向一个动态类型不是被投类型的对象时,你会得到一个空指针作为结果。
在你的例子中,你间接地通过空指针并试图调用一个成员函数,结果导致了未定义的行为。
当使用动态转码时,你必须始终检查你是否得到了null。
如果我使用reinterpret_cast...
那么行为仍将是未定义的,因为你将通过一个指向不存在的对象的指针进行间接调用。除非你创建一个派生类的实例,否则你不能调用它的非静态成员函数。
例如,你可以像这样将一个基类实例转换为派生类。
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;
}