将层次结构向下投射为具体对象

Casting down the hierarchy a concrete object

本文关键字:对象 层次结构      更新时间:2023-10-16

我正在看一段代码,其中有一个c风格的转换让我感到困惑。

我对cast很熟悉,但是这个我真的不能掌握。这里是:我有两个类,比如说Base和Derived,但是Derived没有添加任何方法/属性。基本上,这只是Base的一个特殊情况,当它的一个属性(称为M_blockSize)被固定为1;但是,这些方法都不需要特定的实现,也没有功能扩展。这种派生类的好处并不是这个线程的重点。让我们假设开发人员有他们这样做的充分理由。

无论如何,在这段代码中,我看起来像这样:

void foo(const Derived& d){...}
[...]
Base b;
foo((Derived&) b);
因此,开发人员将基对象强制转换为对派生对象的引用。在我的理解中,如果"castee"(b)的具体类型确实是派生的,则进行下浇。

然而,这是c风格的强制转换,所以编译器正在尝试一大堆强制转换,我不知道哪一个最终有效。

所以问题:

  • 1)编译器在做什么类型转换?我假设是reinterpret_cast ?
  • 2)Derived&(b)也能工作吗?
  • 3)如果类派生添加了一些方法/属性(未在foo中使用),这还会工作吗?
  • 4)的关键点是foo不使用派生的任何功能,是不是已经在基础?
我希望你的问题很清楚。谢谢你的帮助。

这里生效的强制转换是static_cast<Derived&>,由以下规则(§5.2.9静态强制转换)控制:

类型的左值" cv1 B,"B在哪一个类类型,可以将类型"引用 cv2 D,"D在哪一个类派生从B(条款10),如果一个有效的标准从"D指针"转换到"B指针"的存在(4.10), cv2 cv-qualification一样,或cv-qualification大于 cv1 ,和B既不是虚拟基类的D也不是D虚拟基类的基类。结果类型为"cv2 D ."

将"指向D的指针"强制转换为"指向B的指针"是一个有效的标准转换(第4.10节):

类型为"指向cv D"的右值,其中D是类类型,可以转换为类型为"指向cv B"的右值,其中BD的基类(第10条)。

然而,仅仅因为演员阵容有效,并不意味着可以这样做。注意(§5.2.9):

如果类型为"cv1 B"的对象实际上是类型为D的对象的子对象,则结果指向类型为D的封闭对象。否则,强制转换的结果是未定义的。

所以这段代码导致了未定义的行为。可以从基类强制转换到它的任何派生类,但是只有当它确实是派生类型的对象时,才能定义行为。

所以要回答这些问题:

  1. 这是static_cast<Derived&> .
  2. 是的,因为这就是发生的事情。
  3. 它不工作,因为它导致未定义的行为。
  4. 我不能确定这里的重点是什么。如果您在foo中不使用任何Derived特定的功能,我希望它可能继续按预期执行。但是,如果是这种情况,只需采取Base&