为什么虚拟赋值运算符是“一罐蠕虫”?

4

我的教科书说,虚拟赋值运算符“在教程范围之外打开了一个新的问题”。

虚拟化赋值运算符是可能的。然而,与析构函数的情况不同,在那里虚拟化总是一个好主意,虚拟化赋值运算符确实会打开一个充满许多高级主题的问题,并超出了本教程的范围。因此,我们建议您现在将您的赋值操作保持为非虚拟化,以简化起见。

这是什么意思?你能用一个小例子解释一下这本书所指的问题吗?为什么虚拟赋值运算符特别呢?


一般而言,赋值运算符和继承混合在一起是个坏主意。如果不妥善考虑,可能会出现许多问题,例如对象截断。更不用说加入虚继承之后,就有更多需要正确处理的特殊情况了。 - spectras
最好能够总结或提供有关教程示例的链接以提供上下文。 - 463035818_is_not_a_number
编辑,要求链接或离线资源被视为离题。 - 463035818_is_not_a_number
在互联网上搜索"C++对象切割"。 - Thomas Matthews
好的,我会的,谢谢@ThomasMatthews! :) - patch99000
1个回答

1
让我们以经典的形状示例为例:

class Shape
{
  public: virtual bool operator==(const Shape & s) const = 0;
};

class Rectangle : public Shape
{
  public: bool operator==(const Shape & s) const
  { /*...*/ }
};

class Circle : public Shape
{
  public: bool operator==(const Shape & s) const
  { /*...*/ }
};  

现在进入有趣的部分。
Rectangle r;
Circle c;
Shape * p_shape1 = &r; // This is legal.
Shape * p_shape2 = &c; // So is this.

// What happens here????
if (r == *p_shape2)
{
  //...
}

在我看来,运算符不应该被继承。不能保证 Child1 的运算符将传递给 Child1 实例;它们可能会传递给 Child2 或 Child3,甚至是 GrandChild1 实例。

分配后更有趣! - Eljay
这与运算符无关。该函数被定义为接受一个 Shape const& 参数,它只能假设这一点。编写虚拟等号运算符通常涉及到 dynamic_cast。无论如何,OP 是在询问赋值运算符。 - Sneftel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接