这是我在这个网站上的第一个问题,所以请随意突出我的单词选择,问题结构等问题。
最近,我在处理多态时开始使用dynamic_cast
,并且我已经读过dynamic_cast
不创建该类的另一个实例,而是创建另一个指向该实例的指针实例对象
在测试dynamic_cast
时,我遇到了这个问题。这是代码:
//main.cpp
#include <iostream>
class Base{
public:
int BaseNum;
virtual void BaseFunction(){};
};
class Derived : public Base{
public:
int DerivedNum;
virtual void DerivedFunction(){};
};
int main(){
Base * ptrBase = new Base;
ptrBase->BaseNum = 0;
Derived * ptrDerived = dynamic_cast<Derived *>(ptrBase);
ptrDerived->DerivedNum = 1;
std::cout << ptrBase->BaseNum << ptrDerived->DerivedNum << std::endl;
system("pause");
return 0;
}
程序崩溃了:
ptrDerived->DerivedNum = 1;
在调试时,它说“无法读取内存”。我的结论是,如果原始内存分配是为层次结构中较高的类保留的,那么我无法转发,但我认为我可能错了。
代码哪里出错了?
答案 0 :(得分:7)
dynamic_cast
在指定对象中查找请求的类类型,并返回指向该对象部分的指针/引用。如果找不到,则为指针强制转换返回NULL,并为引用强制转换抛出std::bad_cast
异常。在您的示例中,它失败,因为ptrBase
没有指向作为Derived
类的实例的对象,因此对象中没有Derived
部分返回指针,所以它返回NULL。你需要改变这个:
Base * ptrBase = new Base;
改为:
Base * ptrBase = new Derived;
答案 1 :(得分:3)
您的问题是您正在使用动态强制转换。
如果你做了
Base *ptrBase = new Derived ;
然后它会起作用。
派生的IS A Base。 基础不是衍生的。
答案 2 :(得分:1)
在示例代码中,您创建了Base
的新实例:
Base * ptrBase = new Base;
ptrBase->BaseNum = 0;
Derived * ptrDerived = dynamic_cast<Derived *>(ptrBase);
由于Derived
是Base
的超集,但base只是Derived
的一个子集,因此您无法将ptrBase
指向的对象称为{{1}因为它更小&#39;比Derived
。
另一方面,如果你写了
Derived
然后一切都很好,因为现在Base * ptrBase = new Derived;
ptrBase->BaseNum = 0;
Derived * ptrDerived = dynamic_cast<Derived *>(ptrBase);
指向的对象是ptrBase
。
使用Derived
,由程序员决定转换是否成功。