【问题标题】:Why does dynamic_cast give nullptr with private inheritance here?为什么 dynamic_cast 在这里给 nullptr 提供私有继承?
【发布时间】:2014-10-24 16:45:14
【问题描述】:

谁能给我解释一下:

struct A {
    virtual ~A() = default;
};

struct B : private A {
    void foo() {
        B* b = new B;
        std::list<A*> list = {b};
        B* back = dynamic_cast<B*>(list.back());
        std::cout << back << std::endl;
    }
};

int main() {
    B b;
    b.foo();  // nullptr
}

据我了解,只有 B 知道 B 是从 A 派生的。foo() 是 B 的成员函数。因此在 B::foo() 中从 A* 到 B* 的 dynamic_casting 应该没问题。那么为什么结果是 nullptr 呢?如果它是受保护的继承,也会发生同样的事情。将继承改为public,一切正常。这是怎么回事?

【问题讨论】:

    标签: c++ inheritance private


    【解决方案1】:

    dynamic_cast&lt;T&gt;(v) 执行其运行时检查的方式在 §5.2.7 [expr.dynamic.cast]/p8 中指定:

    如果CT 指向或引用的类类型,则运行时 check 逻辑执行如下:

    • 如果,在v 指向(引用)的最派生对象中,v 指向(引用)public 基类子对象C 对象, 如果只有一个 C 类型的对象是从子对象派生的 v 指向(引用)o 结果指向(引用)那个 C 对象。
    • 否则,如果v 指向(指)一个public 最派生对象的基类子对象,以及最派生对象的类型 有一个C 类型的基类,它是明确的,public 是 结果指向(指)最派生的C 子对象 对象。
    • 否则,运行时检查将失败。

    请注意,只有公共基地的检查才会成功。

    【讨论】:

    • 好的,谢谢。我猜规则就是规则。那么我认为私有继承的定义应该包括上面的规则,否则我读到的定义误导了我。
    猜你喜欢
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2013-10-23
    • 2018-12-11
    • 1970-01-01
    • 2012-09-27
    • 2023-03-31
    相关资源
    最近更新 更多