Dynamic_cast在三级继承的情况下会导致分段冲突
dynamic_cast causes segmentation violation in case of three level inheritance
似乎dynamic_cast
在三级继承的情况下不起作用。
应用程序在print()
方法调用点(在main()
中)由于分割错误(核心转储)而崩溃。
代码如下:
#include <iostream>
#include <typeinfo> //must be included to call any member functions for the typeinfo object returned by typeid()
using namespace std;
class CBase
{
public:
virtual void print()
{
cout<<"CBase::print"<<endl;
}
virtual ~CBase()
{ }
};
class CDerivedA : public CBase
{
public:
virtual void print()
{
cout<<"CDerivedA::print"<<endl;
}
virtual ~CDerivedA()
{}
};
class CDerivedB : public CDerivedA
{
public:
void print()
{
cout<<"CDerivedB::print"<<endl;
}
};
int main()
{
CBase* ptrB = new CDerivedA();
CDerivedB* ptrDB = dynamic_cast<CDerivedB*>(ptrB);
ptrDB->print();
return 1;
}
"指向CDerivedA的指针"(基类)不能强制转换为"指向CDerivedB的指针"(派生类)。注意,我不是指声明的指针类型;问题是指向的实际对象实际上是基类的一个实例,因此向下转换不能成功。
dynamic_cast
在向下转换失败的情况下返回null
指针,这可能是分割冲突的原因(在转换引用的情况下,它将抛出bad_cast
异常)。
注意dynamic_cast
需要RTTI(运行时类型信息)才能正常工作。出于性能原因,可以在编译器中关闭RTTI(因为如果启用RTTI,会在运行时引入一些开销)。请再次检查是否在编译器中启用了RTTI。
编辑:关于你最后的评论-
Downcasting基础知识
不能向下转换基类的实例。您可以向下转换声明为"指向基类的指针"的指针,该指针实际上指向派生类的实例。一个如何使用向下转换的例子:
class Base
{ public:
virtual void baseMethod() {cout<<"baseMethod in Base"<<endl;}
// I am omitting virtual destructors here for brevity,
// which you should _not_ do in your code!
}
class Derived : public Base
{ public:
void baseMethod() {cout<<"baseMethod in Derived"<<endl;}
virtual void derivedMethod(){cout<<"derivedMethod in Derived"<<endl;}
}
class Derived2 : public Derived
{ public:
void baseMethod() {cout<<"baseMethod in Derived2"<<endl;}
void derivedMethod(){cout<<"derivedMethod in Derived2"<<endl;}
void derived2Method(){cout<<"derived2Method in Derived2"<<endl;}
}
void someFunction(Base* pBase)
{
// pBase may actually point to an instance of Base, Derived or Derived2.
// But you can invoke only 'baseMethod' on pBase,
// since 'derivedMethod' and 'derived2Method' are not declared in Base.
pBase->baseMethod(); // ok
// ERROR: pBase->derivedMethod();
// ERROR: pBase->derived2Method();
// To invoke 'derivedMethod', you have to downcast to Derived:
Derived* pDerived = dynamic_cast<Derived*>(pBase);
if(pDerived /* != null */)
{
// Downcast successful, i.e.
// pBase actually points to an instance of Derived _or_ Derived2.
// Both have the 'derivedMethod', so you can invoke it via 'pDerived' pointer:
pDerived->derivedMethod(); // ok
// ERROR: pDerived->derived2Method();
// To call 'derived2Method', you have to downcast to Derived2.
}
else
{
// If we are here, then dynamic_cast returned null,
// i.e. the downcast was NOT successful
// and pBase actually points to an instance of Base.
}
}
避免投
你应该试着设计你的程序,这样就不需要强制类型转换了。使用多态性代替。在基类中声明所有需要的方法。使用纯虚方法。
将基类升级为派生类
不能通过强制转换升级实例。如果您想将Base
的实例升级到Derived
的实例,那么你必须在Derived
中定义一个以Base为参数的构造函数,并通过new
创建一个派生的新实例。注意,Base
的旧实例保持原样,只创建了Derived
的新实例。
class Derived : public Base
{ public:
Derived(Base& base)
: Base(base) // use copy constructor of Base
{
// initializations specific to Derived
}
// ... other methods ...
}
// Usage:
Base* pBase = new Base();
Derived* pDerived = new Derived(*pBase); // "upgrade" Base to Derived.
// The instance of Base (pointed to by pBase) still lives,
// and a new instance of Derived (pointed to by pDerived) is born.
// Do not forget to delete both pBase and pDerived!
我希望这对你有帮助。
非常感谢Tadeusz Kopec的更正。
相关文章:
- 在没有太多条件句的情况下,我如何避免被零除
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 在未初始化映射的情况下,将值插入到映射的映射中
- 是默认情况下分配给char数组常量的值
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在已经使用Git的情况下减少编译时间
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 如何在没有信号的情况下从C++执行QML插槽
- 如何在不知道向量大小的情况下输入向量内部的向量?
- 为什么在某些情况下不写入此文件?
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 在没有Xcode的情况下在Mac捆绑包中嵌入框架
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 在C++中如何在没有pow的情况下进行基础计算
- 在链接的程序集文件中,我想从 c++ 调用代码访问变量.是否可以在不触发访问冲突的情况下执行此操作?
- 如何在不与标准库运算符冲突的情况下为一组相关类重载运算符?
- c++模板和const(使用auto在没有编译器警告的情况下发生冲突)
- Dynamic_cast在三级继承的情况下会导致分段冲突