简体   繁体   中英

copy and swap technique uses copy constructor inside assignment operator function

I was reading "Effective C++ by Scott Meyers", in which Item 11 is recommending is to use the "copy and swap" technique inside my assignment operator:

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

But in Item 12 it is written:

It makes no sense to have copy assignment operator call the copy constructor.

I think that Item 11 and Item 12 are contradictory. Am I understanding it incorrectly?

In the 2 citations of "Effective C++ by Scott Meyers" that you mention the 2 different aspects are discussed.

  • In the code fragment in Item 11 Scott shows one of the ways to implement the assignment operator.
  • In Item 12 the citation you mention deals with avoiding code duplication between the assignment operator and copy constructor. One paragraph above your citation says:

the two copying functions will often have similar bodies, and this may tempt you to try to avoid code duplication by having one function call the other.

My understanding of this part of Item 12 is like this: if you try to write something like below (to have copy assignment operator call the copy constructor) then it will be wrong:

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;
}

I do the opposite. I overload the assignment operator to do a "deep" copy (meaning you consider dynamic memory and instantiate new copies accordingly). Then use the assignment operator in copy constructor. Can't comment on your text because I don't have that book.

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM