在基类对象上使用派生指针,会调用哪些重写方法?

问题描述 投票:0回答:1

我遇到了一种情况,我认为会导致问题,但现在我不太确定。

我正在查看的代码有一个基类和派生类,基类中的方法在派生类中被重写。它创建一个基础对象并将其静态转换为派生类型:

Derived *d = static_cast< Derived * >( new Base( x, y, z ) ); d->overridden_method();

认为在这种情况下调用重写的方法会导致base类方法被执行,因为底层对象本身属于该类,因此vtable条目将引用基类函数。

但是,在这种情况下看起来像是调用了

driven 方法。这是预期的吗?

我发现了很多关于另一种方式的东西(从基础铸造),但我在尝试找到有关此场景的任何信息时却失败了。我相信,在基类指针上调用重写的函数将调用派生方法。否则,这样的事情肯定行不通:

for ( const auto &shape : shapes ) { shape.draw(); // Handles any sort of derived shape. }


顺便说一句,在你说我们

不应该进行派生转换之前,请注意这是我们继承的代码,我们实际上正在尝试解决这个问题(如果我错了,那就不是问题) ).

但是,当我创建一个单元测试来说明问题时(这样我就知道何时修复它),看起来

is没有问题。于是就有了这个问题。

c++ inheritance derived-class
1个回答
0
投票
将实际指向基对象的指针转换为派生类型是未定义的行为。引用自

expr.static.cast(强调我的)

“指向 cv1 B 的指针”类型的纯右值,其中 B 是类类型,可以是 转换为“指向 cv2 D 的指针”类型的纯右值,其中 D 是 从 B 派生的完整类,如果 cv2 与 cv 限定相同, 或比 cv1 更高的 cv 资格。如果 B 是一个虚拟基类 D 或 D 的虚拟基类的基类,或者如果没有有效的 存在从“指向 D 的指针”到“指向 B 的指针”的标准转换 ([conv.ptr]),程序格式错误。空指针值 ([basic.compound]) 被转换为空指针值 目的地类型。

如果“pointer to cv1 B”类型的纯右值指向 A B 实际上是 D 类型对象的基类子对象, 结果指针指向 D 类型的封闭对象。 否则,行为是未定义的。

您的指针未指向有效的基类子对象,因此行为未定义。

© www.soinside.com 2019 - 2024. All rights reserved.