我正在查看一段代码,其中有一个令我困惑的C风格演员。
我对铸造相当熟悉,但这个我真的无法掌握。所以,这里是:我有两个类,比如Base和Derived,但是Derived没有添加任何方法/属性。基本上它只是Base的一个特例,当它的一个属性(称为M_blockSize)被固定为1时;但是,没有一种方法需要特定的实现,也没有功能的扩展。这种Derived类的好处不是这个线程的重点。让我们假设开发人员有充分的理由。
无论如何,在这段代码中,我看起来像这样:
void foo(const Derived& d){...}
[...]
Base b;
foo((Derived&) b);
因此,开发人员将基础对象转换为对派生对象的引用。根据我的理解,如果“castee”(b)的具体类型确实是Derived,则进行向下转换。这不是这种情况。
然而,这是c风格的转换,所以编译器正在尝试一大堆演员,我不知道它最终会起作用。
所以,问题:
我希望问题很清楚。谢谢你的帮助。
答案 0 :(得分:1)
这里生效的演员阵容是static_cast<Derived&>
,由以下规则管辖(§5.2.9静态演员):
类型为“ cv1
B
的左值”,其中B
是类类型,可以强制转换为“引用 cv2D
,“其中D
是B
派生的类(第10条),如果存在从”D
指针到“指针B”的有效标准转换(4.10), cv2 与 cv1 具有相同的cv资格,或更高的cv资格,B
既不是D
的虚拟基类{1}}也不是D
的虚拟基类的基类。结果的类型为“ cv2D
。”
将“指向D
”的指针转换为“指向B
的指针”是有效的标准转换(§4.10):
类型为“指向 cv
D
的指针”的prvalue,其中D
是类类型,可以转换为“指向的指针的prvalue” cvB
“,其中B
是D
的基类(第10条)。
然而,仅仅因为演员表演,并不意味着可以这样做。注(§5.2.9):
如果类型为“ cv1
B
”的对象实际上是类型为D
的对象的子对象,则结果引用类型为{{1}的封闭对象}}。否则,演员表的结果是未定义的。
因此,此代码会导致未定义的行为。您可以从基类转换为其任何派生类,但如果它确实是该派生类型的对象,则只有定义行为。
所以回答问题:
D
。static_cast<Derived&>
内使用任何Derived
特定功能,我希望可能继续按预期执行。但是,如果是这种情况,请选择foo
。