将层次结构向下转换为具体对象

时间:2013-03-20 16:41:08

标签: c++ casting derived-class

我正在查看一段代码,其中有一个令我困惑的C风格演员。

我对铸造相当熟悉,但这个我真的无法掌握。所以,这里是:我有两个类,比如Base和Derived,但是Derived没有添加任何方法/属性。基本上它只是Base的一个特例,当它的一个属性(称为M_blockSize)被固定为1时;但是,没有一种方法需要特定的实现,也没有功能的扩展。这种Derived类的好处不是这个线程的重点。让我们假设开发人员有充分的理由。

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

void foo(const Derived& d){...}
[...]
Base b;
foo((Derived&) b);

因此,开发人员将基础对象转换为对派生对象的引用。根据我的理解,如果“castee”(b)的具体类型确实是Derived,则进行向下转换。这不是这种情况。

然而,这是c风格的转换,所以编译器正在尝试一大堆演员,我不知道它最终会起作用。

所以,问题:

  • 1)编译器在做什么?我假设有一个reinterpret_cast吗?
  • 2)static_cast<衍生的放大器; >(b)也工作?
  • 3)如果Derived类添加了一些方法/属性(在foo中没有使用),这还能用吗?
  • 4)foo不使用Derived中尚未存在的任何功能的关键点是什么?

我希望问题很清楚。谢谢你的帮助。

1 个答案:

答案 0 :(得分:1)

这里生效的演员阵容是static_cast<Derived&>,由以下规则管辖(§5.2.9静态演员):

  

类型为“ cv1 B的左值”,其中B是类类型,可以强制转换为“引用 cv2 D,“其中DB派生的类(第10条),如果存在从”D指针到“指针B”的有效标准转换(4.10), cv2 cv1 具有相同的cv资格,或更高的cv资格,B既不是D的虚拟基类{1}}也不是D的虚拟基类的基类。结果的类型为“ cv2 D。”

将“指向D”的指针转换为“指向B的指针”是有效的标准转换(§4.10):

  

类型为“指向 cv D的指针”的prvalue,其中D是类类型,可以转换为“指向的指针的prvalue” cv B“,其中BD的基类(第10条)。

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

  

如果类型为“ cv1 B”的对象实际上是类型为D的对象的子对象,则结果引用类型为{{1}的封闭对象}}。否则,演员表的结果是未定义的。

因此,此代码会导致未定义的行为。您可以从基类转换为其任何派生类,但如果它确实是该派生类型的对象,则只有定义行为。

所以回答问题:

  1. 这是D
  2. 是的,因为那就是发生的事情。
  3. 它无论如何都不起作用,因为它会导致不确定的行为。
  4. 我无法确定这里有什么意义。如果您不在static_cast<Derived&>内使用任何Derived特定功能,我希望可能继续按预期执行。但是,如果是这种情况,请选择foo