请看下面的 C++20 程序:
struct B { B(); private: int whatever; }; // non-aggregate
struct D : B { D(); int x; private: int whatever2; }; // non-aggregate
int main() {
D* d = new D;
d->x = 42;
B* b = (B*) d;
D* d2 = (D*) b;
return d2->x;
}
这个程序是否不规范或存在未定义行为?
也就是说,将非多态类型的派生对象的基类子对象的指针转换成指向派生对象本身的指针是允许的吗?
如果允许,那么 *_cast<T>
函数中的哪一个比 C 风格的转换更合适?
(此外,如果指针指向的是不是类型为 D
的对象的基类子对象,则它是未定义的行为,对吗?实现无法像使用 dynamic_cast
那样检查转换是否正确?)
B* b = d
就可以了。 从B转回D,你需要进行强制类型转换。至于哪种转换形式,如果您知道您的B实际上是一个D,则D* d2 = static_cast <D*> (b)
是首选的C++方式。 如果您不确定,则D* d2 = dynamic_cast <D*> (b)
将按预期进行转换,如果b
是D*
,则它会产生空指针。请注意,dynamic_cast
会产生一些运行时成本。 - Perettedynamic_cast
。但是对于其他部分,您是正确的,static_cast
是首选方法。 - Guillaume Racicot