【问题标题】:The reason why dynamic_cast doesn't work with non-polymorphic typesdynamic_cast 不适用于非多态类型的原因
【发布时间】:2016-03-01 17:33:21
【问题描述】:

使用类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++ 要求源类型是多态的?我发现的唯一解释是this,但它只是说“因为它是在内部实现的”——至少在我看来)。设计dynamic_cast 的人可能还有其他一些原因——那些是什么?

【问题讨论】:

  • 我没有看到任何动态多态的东西。您在基类中至少缺少一个 virtual 析构函数。
  • 在发布充满错误的代码之前,请使用编译器。
  • @DieterLücking 确实如此,但确切的代码不是这里的重要部分。我想说,这足以证明意图。

标签: c++ polymorphism dynamic-cast


【解决方案1】:

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

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

【讨论】:

  • 所以多态类型的对象或多或少地存储了有关其真实类型的信息?
  • @user5539357 是的。他们需要以某种形式或形式存储这些信息,以便能够正确地进行动态调度(虚拟功能)。
【解决方案2】:

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

【讨论】:

  • 这不是实现细节吗?
猜你喜欢
  • 2019-02-09
  • 1970-01-01
  • 2013-02-13
  • 1970-01-01
  • 1970-01-01
  • 2017-11-03
  • 1970-01-01
  • 2012-06-05
  • 2011-01-08
相关资源
最近更新 更多