首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在动态强制转换后尝试从子类访问受保护变量时引发的异常。

在动态强制转换后尝试从子类访问受保护变量时引发的异常。
EN

Stack Overflow用户
提问于 2022-01-06 19:37:52
回答 1查看 80关注 0票数 -1

我试着在C++中学习动态铸造。

因此,我开发了两个类来测试一些与动态铸造相关的内容:

代码语言:javascript
复制
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

代码语言:javascript
复制
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个。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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结果的尝试都会产生未定义的行为。

只是碰巧做了你想做的事,但这并不能保证。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70612729

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档