dynamic_cast不适用于非多态类型的原因
The reason why dynamic_cast doesn't work with non-polymorphic types
使用 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 或转换后的指针)。
相关文章:
- 通过switch和static_cast访问多态对象的运行时类型
- 当目标指针不是基类的类型时,为什么允许dynamic_cast为多态类生成 null 指针?
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?
- 如何使用静态多态性在 int 和指针类型之间进行转换?
- 如何调用指针类型的方法(禁用多态性)?
- 如何在不同类型的值之间进行选择以传递给多态函数?
- C++ 多态模板类,模板类型对象的实例化
- 如何多态地使用替代类型的 std::变体
- 对于多态类型T,如何在没有类型T实例的情况下获得指向T的虚拟表的指针
- 哈希多态类型的正确方式
- C++ 2D shared_ptr数组使用抽象多态类型初始化
- 一个类似 std::访问的函数,用于访问多态类型
- 有没有优雅的方法可以在多态 lambda 中编写类型别名
- 多态值类型和接口
- 将unique_ptr返回到多态类型
- 为什么删除的复制构造函数不允许使用其他具有多态类型的构造函数?
- 如何为多态性中的指定类型分配内存
- C 多态性:允许模棱两可的成员类型
- Sean Parent:对于继承层次结构中的多态类型,具有可变对象是极端的例外
- 通过指向非多态类型的基类的指针获取已分配内存的地址