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
Base
的 Hello()
方法,它会使应用程序崩溃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;
}
我有两个 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
Base
的 Hello()
方法,它会使应用程序崩溃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;
}