【问题标题】:Dynamic_cast on non polymorphic types非多态类型上的 Dynamic_cast
【发布时间】:2019-02-09 18:04:38
【问题描述】:

我可以理解为什么在这种情况下 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&lt;void*&gt;/typeid会做的那样),知道了真实类型之后,才知道该类型是否派生自一个非多态基?

【问题讨论】:

  • 想想 vtable 然后想想 vptr。你需要哪个vtable?哪个对象需要 vptr?

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


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多