复制和交换技术在赋值操作符函数内部使用复制构造函数

copy and swap technique uses copy constructor inside assignment operator function

本文关键字:复制 内部 构造函数 函数 赋值操作符 交换 技术      更新时间:2023-10-16

我正在阅读"Effective c++ by Scott Meyers",其中第11项建议在我的赋值操作符中使用"复制和交换"技术:

Widget& Widget::operator=(const Widget &rhs)
{
    Widget temp(rhs); // Copy constructor
    swap(temp); //Swap with *this
    return *this;
}

但是在第12项中写着:

让复制赋值操作符调用复制构造函数没有意义。

我认为第11项和第12项是矛盾的。我理解错了吗?

在您提到的《Effective c++ by Scott Meyers》的两处引用中,讨论了两个不同的方面。

    在第11项的代码片段中,Scott展示了一种实现赋值操作符的方法。
  • 在第12项中,您提到的引用涉及避免赋值操作符和复制构造函数之间的代码重复。引文上面的一段说:

两个复制函数通常具有相似的主体,这可能会促使您尝试通过一个函数调用另一个函数来避免代码重复。

我对第12项这部分的理解是这样的:如果你试图写下面的东西(让复制赋值操作符调用复制构造函数),那么它将是错误的:

PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs)
: Customer(rhs),   // invoke base class copy ctor
  priority(rhs.priority)
{
  logCall("PriorityCustomer copy constructor");
}
PriorityCustomer&
PriorityCustomer::operator=(const PriorityCustomer& rhs)
{
  logCall("PriorityCustomer copy assignment operator");
  this->PriorityCustomer(rhs); // This line is wrong!!!
  return *this;
}

我的做法正好相反。我重载赋值操作符来执行"深度"复制(这意味着您考虑动态内存并相应地实例化新的副本)。然后在复制构造函数中使用赋值操作符。我不能评论你的文章,因为我没有那本书。

Widget::Widget(const Widget& existing) : dynamicThingie(0)
{
    *this = existing;
}

Widget& Widget::operator=(const Widget& existing)
{
    a = existing.a;
    b = existing.b;
    delete dynamicThingie;
    dynamicThingie = new Thingie();
    memcpy(dynamicThingie, existing.dynamicThingie, lengthOfDynamicThingue);
    return *this;
}