Dynamic_cast 非多态类型

Dynamic_cast on non polymorphic types

我能理解为什么 dynamic_cast 在这种情况下有效:

#include <iostream>

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

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

struct C : A, B{};

void f(const A &a) {
    if(auto p = dynamic_cast<const B*>(&a))
        std::cout << "a is a B" << std::endl;
}

int main() {
    f(C{});

    return 0;
}

但是为什么如果从 B 中删除多态性它仍然有效:

#include <iostream>

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

struct B {
};

struct C : A, B{};

void f(const A &a) {
    if(auto p = dynamic_cast<const B*>(&a))
        std::cout << "a is a B" << std::endl;
}

int main() {
    f(C{});

    return 0;
}

是不是因为dynamic_cast必须只知道你给的对象的真实类型有一个参数(如dynamic_cast<void*>/typeid会做),知道真实类型后,它就知道了如果该类型派生自非多态基础?

根据标准 ([expr.dynamic.cast]p6),您投射的对象应该具有多态类型,而不是您试图投射到的对象。

如果你仔细想想,这是绝对合乎逻辑的。 dynamic_cast 需要一些信息来进行转换 (RTTI),并且此信息与多态类型相关联。因此,该类型的父类型是否为多态并不重要,关于此 class 的信息就在这里。您无需知道其他人的 class RTTI 即可将 this 对象投射给它。你只需要知道这个对象是否真的与你想要将它转换成的对象有某种关系。