gpt4 book ai didi

c++ - 在两个派生类之间进行转换

转载 作者:太空狗 更新时间:2023-10-29 20:39:45 25 4
gpt4 key购买 nike

在具有共同祖先的类的指针之间转换是否合法?编译器是否注意到这样的层次结构并确保其安全(调用 1)?或者用户是否必须手动通过层次结构才能始终安全(调用 2)?

说我们有

class A{};
class B:A{};
class C:A
{
public:
int SomeFunc(){return 3;}
};

int _tmain(int argc, _TCHAR* argv[])
{
B* b = (B*)((A*)new C()); // this is done manually, i believe it is safe

((C*)b)->SomeFunc(); // is this safe? this is the cast in question

return ((C*)((A*)b))->SomeFunc(); // this is done manually, i believe it is safe
}

编辑:使这段代码可编译和运行

edit2:添加了更多评论

最佳答案

B* b = (B*)((A*)new C()); // this is done manually, i believe it is safe

安全。
粗略地说,(T) expr 形式的转换被转换为 static_castreinterpret_cast。 [expr.cast]/4:

The conversions performed by

  • a const_cast (5.2.11),
  • a static_cast (5.2.9),
  • a static_cast followed by a const_cast,
  • a reinterpret_cast (5.2.10), or
  • a reinterpret_cast followed by a const_cast,

can be performed using the cast notation of explicit type conversion. The same semantic restrictions and behaviors apply […]
If a conversion can be interpreted in more than one of the ways listed above, the interpretation that appears first in the list is used, even if a cast resulting from that interpretation is ill-formed.

您可以在这里忽略 const_cast,因为您的代码中没有进行资格转换。static_cast 在两种转换中都足够,第一个转换为 (A*),第二个转换为 (B*)。第一个就好了。向上转型从来都不是问题。
第二个会引发未定义的行为。 [expr.static.cast]/11:

A prvalue of type “pointer to cv1 B,” where B is a class type, can be converted to a prvalue of type “pointer to cv2 D”, where D is a class derived (Clause 10) from B, if a valid standard conversion from “pointer to D” to “pointer to B” exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and B is neither a virtual base class of D nor a base class of a virtual base class of D. […] If the prvalue of type “pointer to cv1 B” points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the result of the cast is undefined.

另请注意,仅仅因为 static_cast 触发了 UB,并不意味着它未被选中(并被 reinterpret_cast 取代)。

第二个和第三个转换基于第一个(这会导致未定义的行为),因此谈论它们的有效性是没有意义的。

关于c++ - 在两个派生类之间进行转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26733828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com