我对dynamic_cast非常困惑。 C++ Primer和cppreference(规则5)中的内容无法帮助我理解。 (推荐比书难得多,我都非常仔细地阅读了它们)

从C++ Primer 5th:dynamic_cast<type*>(e)


因此,这就是我对上面引用的文本的理解:

(基类具有虚函数)
dynamic_cast成功,如果:

  • e是从type继承的公共(public)继承类。 e是 child 。 cast。
  • etype的基类? type是 child 。沮丧。
  • etype相同。边播?


  • 样例代码:
    #include <iostream>
    using namespace std;
    
    struct A {
        virtual void foo() {}
    };
    
    struct B : A {
    
    };
    
    struct C : B {
    
    };
    
    int main()
    {
        A* pa = new B;
        if (C* pc = dynamic_cast<C*>(pa)) {
            cout << "1";    //B is a base class of C
        }
        return 0;
    }
    

    我不明白为什么这次失败会失败,我认为它满足条件2和规则5)(来自cppreference)。

    如果这本书是错误的(再次该死),有人会从cppreference中详细说明rule 5)吗?没有例子我无法完全理解它的意思...

    最佳答案

    这是cppreference中带有我的注释的规则:



    这适用。 BC的基础。


    pa指向的最直接的对象是B类型。

    尽管BC的公共(public)基础,但是pa指向的特定实例不是B实例的C基础子对象的实例。指向的B实例是一个“具体”对象。因此,这种情况不适用。

    一个例子:

    C  c;
    B* bp = &c; // bp points to base subobject of C
    C* cp = dynamic_cast<C*>(bp);
    assert(cp);
    
    B  b2;
    B* bp2 = &b2; // bp does not point to a base subobject
    C* cp2 = dynamic_cast<C*>(bp2);
    assert(!cp2);
    


    pa不指向基类为C的大多数派生对象,因此这种情况不适用。

    旁投的示例:
    struct base {
        virtual ~base(){}; // for polymorphism
    };
    struct left : base {};
    struct right : base {};
    struct derived : left, right {};
    
    derived d;
    left* l = &d;
    right* r = dynamic_cast<right*>(l);
    



    5a和5b情况都不适用,因此“其他”情况5c则不适用。



    不是边播。边播将在5b中说明。强制转换为相同类型只是身份转换(非常有用,因此也不是常用的术语)。

    本书尝试的条件可能描述了转换是否格式正确。尽管“那么 Actor 将成功”肯定似乎意味着更多。所引用的规则不是,用于描述强制类型转换在运行时是否成功。

    如果整个程序格式正确,则编译器必须编译该程序。如果表达式格式错误,则编译器必须给您一条诊断消息,指出您做错了。

    您显示的示例程序格式正确,必须成功编译。它确实可以在我的系统上编译。

    10-07 19:22
    查看更多