0

I have a question about assignment operator when using copy-and-swap method.

String & operator = (String s) // the pass-by-value parameter serves as a temporary
{
   s.swap (*this); // Non-throwing swap
   return *this;
}// Old resources released when destructor of s is called.

Let's suppose we have a good copy constructor which deep-copy all the pointers and dynamic allocated variables.

Then, what's the difference between above code and below code?

String & operator = (String s) // the pass-by-value parameter serves as a temporary
{
   return s;
}

Since, we have a good copy constructor, I think another object, s, is created inside the operator= function. So, what's the point of using non-throwing swap function?

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
invictus
  • 81
  • 5

3 Answers3

3

The main difference is that the 2nd operator= doesn't change the current object (i.e. *this) at all.

String a, b;
b = a; // b is not changed at all

And note the 2nd operator= is returning s (which will be destroyed when get out of the function) by reference, so it'll be just a dangled reference.


To be more general, we use copy & swap idiom to provide strong exception safety guarantee, which is something like commit-or-rollback semantics; If an operation terminates because of an exception, program state will remain unchanged.

String & operator = (String s) // Copy construct s. If exception happens here, 
                               // s won't be constructed, 
                               // and the state of the current object (*this) won't be changed
{
   s.swap (*this);             // Use non-throwing swap to commit the change
   return *this;               // Non-throwing operation
}
Community
  • 1
  • 1
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
0

The difference is that in your second code block you create a copy s of the String object, return a reference to it, and then the copy is destructed on scope exit, which causes your program to have undefined behaviour.

pzelasko
  • 2,082
  • 1
  • 16
  • 24
0

There are several main differences:

An assignment operator should return *this (and almost always does). This is what makes chaining assignments possible.

String s1, s2, s3;
s1 = s2 = s3; // Now all strings ave the same value.

Instead, you return a reference to a local variable. It then becomes a dangling reference, since it doesn't point to a valid memory location.

Also, the assignment operator must change the assigned object, which doesn't happen in your code.

And finally, why do we need the non-throwing swap at all? Let's assume your assignment operator throws an exception. What is the state of the assigned object after the failed assignment?

Some implementations might cause the object to be in an invalid state, since the exception was thrown in the middle of changing it.

This is where the swap comes in. Since, the swap never throws, we can be sure the assigned object is in a valid state. If an exception is thrown before the swap, the object still has its old value, and if it was after the swap, the object has its new value.

Or East
  • 115
  • 1
  • 6
  • Assignment doesn't *have to* return `*this`. That's just a really odd convention we've picked up along the way. – Barry Oct 01 '16 at 13:55