dynamic_cast不适用于非多态类型的原因

The reason why dynamic_cast doesn't work with non-polymorphic types

本文关键字:类型 多态 cast 不适用 适用于 dynamic      更新时间:2023-10-16

使用 class B 和派生类D

class B {
    int b;
};

class D : public B {
    int d;
};

D* d = new D();
B* b = dynamic_cast<B*>(d);

以上工作正常 - 这是一个简单的向上转换。我们确信b指向的任何内容都包含B类(子)对象。

然而

B* b = new D();
D* d = dynamic_cast<D*>(b);

即使b指向有效的 D 实例,也不会编译,因为基类不是多态的。因此,仅添加一个空的虚拟方法即可解决问题。

重要的问题是为什么C++要求源类型是多态的?我找到的唯一解释是这个,但它只是说"因为这就是它在内部实现的方式"——至少在我看来)。设计dynamic_cast的人可能还有其他一些原因——那些是什么?

因为如果没有存储在对象中以供运行时使用的某些类型信息,就无法实现dynamic_cast。并且该语言只有两个功能需要有关对象类型的运行时信息:虚函数和dynamic_cast

如果可以使用dynamic_cast来向下转换非多态类型,编译器必须在每个类类型中存储运行时类型信息。这将直接违背C++的"只为你使用的东西付费"的理念,它将彻底破坏它与C和许多外部接口,硬件等的兼容性。基本上不会有标准布局类类型。或者,没有类类型,您可以完全控制其布局。

dynamic_cast

前提是它使用 RTTI(大概每个实现都使用相同的底层数据结构来支持 dynamic_cast 和 RTTI - 类型信息必须存在于某个地方,并且两个用例的不同表示没有意义)来确保您尝试的强制转换在运行时是正确的类型。如果 from-class 是非多态的,则编译器将无法使用类型信息来执行类型检查(以决定返回 0 或转换后的指针)。