非多态类型上的Dynamic_cast

时间:2018-09-04 16:48:11

标签: c++ multiple-inheritance dynamic-cast vtable vptr

我可以理解为什么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那样),并且在知道真实类型之后,才知道该类型是否源自于非多态碱基?

1 个答案:

答案 0 :(得分:8)

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

如果您考虑一下,那绝对是合乎逻辑的。 dynamic_cast需要一些信息以进行强制转换(RTTI),并且该信息与多态类型有关。因此,类型的父级是否是多态的都没有关系,有关此类的信息就在这里。您无需知道其他人的类RTTI即可将 this 对象强制转换为它。您只需要知道此对象与您要将其转换为对象之间是否确实存在某种关系即可。