鉴于此示例:
class Base
{
public:
void foo() {};
};
class Derived : public Base
{
};
int main()
{
Base b;
Derived* d = static_cast<Derived*>(&b);
d->foo();
}
我只有三种情况:当 void foo()
:
- 是
Base
的成员, - 并且当它是
Derived
的成员时, - 以及当它是
Base
和Derived
的成员时。
我的问题是:
成员访问表达式
d->foo()
在这三种情况下都是未定义的行为吗?如果成员访问表达式是 UB,唯一的解决方法是使用
dynamic_cast
吗?
最佳答案
来自the C++ standard §7.6.1.9.11
A prvalue of type “pointer to cv1
B
”, whereB
is a class type, can be converted to a prvalue of type “pointer to cv2D
”, whereD
is a complete class derived fromB
,...
If the prvalue of type “pointer to cv1
B
” points to aB
that is actually a base class subobject of an object of typeD
, the resulting pointer points to the enclosing object of typeD
. Otherwise, the behavior is undefined.
所以使用static_cast
仅当您知道(通过其他方式)强制转换有效时,向下转换才有效。如果您采取 Base
那不是 Derived
并使用 static_cast
为了假装是这样,即使在尝试取消引用指针之前,您也已经调用了未定义的行为。所以你可以删除 d->foo()
line 和仍然有未定义的行为。是 Actor 阵容不好。
如果您的目标是有条件地检查是否有子类的实例,那么您需要 dynamic_cast
.
关于c++ - 这种贬低是否会导致未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71505316/