C++ 将基类强制转换为派生类时,动态_强制转换失败
我有两个类,基类和派生类。 基类有一个虚方法 下面是我的测试示例:C++ 将基类强制转换为派生类时,动态_强制转换失败,c++,polymorphism,dynamic-cast,reinterpret-cast,C++,Polymorphism,Dynamic Cast,Reinterpret Cast,我有两个类,基类和派生类。 基类有一个虚方法 下面是我的测试示例: class Base { public: virtual void Hello() { cout << "-> Hello Base" << endl; } }; class Derived: public Base { public: void Hello() { cout << "-> Hello Derived" << endl; } }; i
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;
}
案例中的结果动态\u cast
:
Segmentation fault (core dumped)
-> Hello Base
将基类强制转换为派生类时,动态_强制转换失败
这是应该发生的事情。当您动态强制转换指向动态类型不是强制转换类型的对象的指针时,您会得到一个空指针作为结果
在您的示例中,您可以通过null指针间接调用一个成员函数,从而导致未定义的行为
使用动态强制转换时,必须始终检查是否为null
如果我使用reinterpret_cast
然后行为仍然是未定义的,因为您将通过指针间接指向不存在的对象。除非创建派生类的实例,否则不能调用其非静态成员函数
可以将基本实例转换为派生实例,例如:
Base b;
Derived d = b;
所发生的情况是,派生实例的基本子对象是从
b
复制初始化的,代码中有两个问题:base
应该有一个虚拟析构函数,因此Dervied
isntances可以通过指向base
的指针正确析构函数。然后,您没有构造类型为派生的
的对象,因此强制转换无法成功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;
}
#包括
使用std::cout;
使用std::endl;
阶级基础
{
公众:
virtual void Hello(){coutBase*mBase=new Base;
应该是Base*mBase=new-Derived;
您创建一个Base
对象,并尝试将其强制转换为无法工作的Derived
(mBase)
将返回空指针,因为mbaase
不指向Derived
对象的Base
子对象,因此您取消引用无效指针。使用reinterpret\u cast
返回的指针也将是未定义的行为,原因相同-mbaase
不指向Base
子对象派生的对象的对象。您希望强制转换更改对象的类型吗?不需要。虚拟析构函数不是多态类型所必需的,至少有一个虚拟方法或构造函数是多态类型。@Jean BaptisteYunès没有虚拟构造函数。虽然从技术上讲,类可能不需要虚拟构造函数orphic,虚拟析构函数对于delete mBase;
具有良好定义的行为是绝对必要的。@Jean BaptisteYunès更改了措辞(并修复了泄漏)@eerorika将编写析构函数,抱歉。“虚拟析构函数是绝对必要的”不,当然不是。在大多数情况下是的,但也有一些情况是不必要的(比如考虑没有字段的类的层次结构)。我知道这是一个建议,但不是必要的。@Jean BaptisteYunès参见标准部分[expr.delete]