动态转换后尝试从子 class 访问受保护变量时抛出异常

Exception thrown when trying to access a protected variable from a child class after a dynamic casting

我正在尝试学习 C++ 中的动态转换。

所以我开发了2个类来测试一些与动态转换相关的东西:

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; }
};

ParentClassEntity.

中定义的方法f2()returnsx

这里是 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; 行,它说:

Exception thrown: read access violation. this was nullptr.

这里奇怪的是x是一个受保护的变量,所以它必须存在于 Entity 和 Player 对象,但是从 Entity 动态转换为 Player 后,新对象无法访问它。

那么异常的原因是什么?

注意:当进行静态转换而不是动态转换时,p->f2() 正常给出 10

dynamic_cast绝不会说谎。它检查对象的运行时类型,看它是否与 dynamic_cast<T> 中的 T gi8ven 匹配。您创建了 Entity 基础 class 的一个实例。此对象的运行时类型是 Entity 因为 那是你创建的

dynamic_cast 知道对象的运行时类型,因此它知道 dynamic_cast<Player*> 无法工作,因为该对象不是 Player 对象。因此,returnsnullptr.

static_cast 不知道对象是否是 Player;它 假定 它是并且 returns 一个指向该对象的指针(如果它存在的话)。但由于它不存在,任何使用 static_cast 结果的尝试都会产生未定义的行为。

这恰好会做你想做的事,但不能保证。