2

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

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

无论如何,在这段代码中,我正在寻找这样的事情:

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

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

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

所以,问题:

  • 1)编译器在做什么转换?我假设一个 reinterpret_cast 也许?
  • 2) static_cast< Derived& >(b) 也可以吗?
  • 3)如果派生类添加了一些方法/属性(未在 foo 中使用),这仍然有效吗?
  • 4) 关键点是 foo 不使用 Derived 的任何尚未在 Base 中的功能吗?

我希望这个问题很清楚。感谢您的帮助。

4

1 回答 1

1

这里的强制转换是 a static_cast<Derived&>,受以下规则(§5.2.9 静态转换)的约束:

cv1 B ”类型的左值,其中是类B类型,可以转换为类型“对cv2 D的引用” ,如果从“指向”到“指向B" 存在 (4.10),cv2与cv1具有相同的 cv 限定或更高的 cv 限定,并且既不是 的虚拟基类,也不是 的虚拟基类的基类。结果的类型为“ cv2 ”。DBDBDD D

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

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

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

如果类型“ cv1 B ”的对象实际上是类型对象的子对象D,则结果引用类型的封闭对象D。否则,强制转换的结果是未定义的。

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

所以回答问题:

  1. 这是一个static_cast<Derived&>
  2. 是的,因为这就是正在发生的事情。
  3. 它无论如何都不起作用,因为它会导致未定义的行为。
  4. 我不能确定这里有什么意义。如果您不使用内部的任何特定功能,我希望它可能会继续按预期执行。但是,如果是这种情况,只需使用.DerivedfooBase&
于 2013-03-20T16:56:14.017 回答