gpt4 book ai didi

c++ - 对象切片或 UB 风险?

转载 作者:行者123 更新时间:2023-11-30 05:25:56 27 4
gpt4 key购买 nike

有几个基类是我无法控制的:-

class BaseNode // Just a POD class. No VTable
{
void foo();
}

class BaseHost
{
public:
BaseNode *getNode()
{
...
}
}

我想“扩展”BaseNode::foo 的功能,但该类实际上是密封的。

建议如下:-

class MyNode: public BaseNode 
{
void foo()
{
// do my stuff..., then
BaseNode::foo();
}
}

class MyHost: public BaseHost
{
public:
MyNode *getNode()
{
return (MyNode*) BaseHost::getNode(); // Slicing or UB risk?
}
}

如果 MyNode 引入额外的类成员或虚拟方法,事情就会变得很糟糕——但如果满足这些约束,我还有 UB 吗?

任何其他问题,或者我是否完全重新考虑设计?

最佳答案

这种向下转型要格外小心:它很容易导致 UB。

标准保证您可以安全地从 MyNode* 转换为 BaseNode*:

4.10/3: A prvalue of type “pointer to cv D”, where D is a class type, can be converted to a prvalue of type “pointer to cv B”, where B is a base class of D. If B is an inaccessible or ambiguous base class of D, a program that necessitates this conversion is ill-formed. The result of the conversion is a pointer to the base class subobject of the derived class object. The null pointer value is converted to the null pointer value of the destination type.

但让我们玩火:标准还允许您在特定条件下从 BaseNode* 转换为 MyNode* :

5.2.9/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 from B, if a valid standard conversion from “pointer to D” to “pointer to B” exists, 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. The null pointer value is converted to the null pointer value of the destination type. 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 behavior is undefined

我尝试将这些引用翻译成纯文本:

  • 如果您确定 BaseHost::getNode() 返回指向 MyNode 对象的向上转换指针,并且您的类层次结构中没有虚拟继承,那么它是好的。
  • 但是如果 BaseHost::getNode() 会返回其他东西(例如,指向普通 BaseNodeBaseNode 的另一个同级派生的指针>) 你将拥有 UB。

如前所述,这很危险:UB 可能已经在指针转换期间发生,甚至在您尝试取消引用指针之前。所以最好尽量避免它。如果你有一个多态的 BaseNode 类(例如,使用虚拟析构函数),你可以使用更安全的 dynamic_cast .

关于c++ - 对象切片或 UB 风险?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38038122/

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