我试着在C++中学习动态铸造。
因此,我开发了两个类来测试一些与动态铸造相关的内容:
class Entity {
protected:
int x = 10;
public:
virtual void f1() { cout << "f1 from Entity class" << endl; }
};
class Player : public Entity {
public:
void f1() { cout << "f1 from Player class" << endl; }
int f2() { return x; }
void f3() { cout << "f3 from Player class" << endl; }
};方法f2()返回在父类Entity中定义的x。
这是main
int main() {
Entity* e = new Entity;
Player* p = dynamic_cast<Player*>(e);
cout << p->f2() << endl;
//the program prints : "p is not null"
if(p == nullptr)
cout << "p is null";
else
cout << "p is not null";
return 0;
}当调用p->f2() (特别是在return x;上)时,会引发一个异常,它说:
引发的
异常:读取访问冲突。这是nullptr。
奇怪的是,x是一个受保护的变量,因此它必须存在于实体和播放器对象中,但是在从实体到播放器的动态转换之后,新对象无法访问它。
那么例外的原因是什么呢?
注意:当做静态铸造而不是动态铸造时,p->f2() 通常会给出10个。
发布于 2022-01-06 19:43:54
dynamic_cast永远不会说谎。它检查对象的运行时类型,以查看它是否与T gi8ven在dynamic_cast<T>中匹配。您创建了Entity基类的实例。这个对象的运行时类型是Entity,因为这是您创建的。
dynamic_cast知道对象的运行时类型,因此它知道dynamic_cast<Player*>不能工作,因为该对象不是Player对象。因此,它返回nullptr。
static_cast不知道对象是否是Player;它假设对象是,并返回指向该对象的指针。但是由于它不存在,任何使用static_cast结果的尝试都会产生未定义的行为。
只是碰巧做了你想做的事,但这并不能保证。
https://stackoverflow.com/questions/70612729
复制相似问题