Jump to content

  • Log In with Google      Sign In   
  • Create Account


What is so bad about self-assignment?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 noatom   Members   -  Reputation: 782

Like
0Likes
Like

Posted 07 April 2013 - 08:50 AM

I was reading Thinking in C++,and I got on overloading the = operator.At the end it warns the coder to always check the possibility of self assignment.But I can't figure out what could go wrong.

 

If I have an object,what could ever happen if I assigned that object to itself? Because I overloaded the = operator,it would probably just put the same values in the same variables.

 

Can someone explain this?



Sponsor:

#2 rip-off   Moderators   -  Reputation: 8119

Like
3Likes
Like

Posted 07 April 2013 - 09:12 AM

Example:
#include <iostream>
#include <algorithm>

class Example
{
public:
    Example(int value) : ptr(new int(value))
    {
    }

    Example(const Example &other) : ptr(new int(*other.ptr))
    {
    }

    ~Example()
    {
        delete ptr;
    }

    Example &operator=(const Example &other)
    {
        delete ptr;
        ptr = new int(*other.ptr);
        return *this;
    }

    int value() const {
        return *ptr;
    }
private:
    int *ptr;
};

int main()
{
    Example a(42);
    std::cout << a.value() << std::endl;
    a = a;
    std::cout << a.value() << std::endl;
}
The core problem is the delete statement, it is deleting the pointer we are going to access on the next line. Now, that implementation is naive, it is not exception safe (if the new statement were to throw, we would leave "this" in an inconsistent state).

While a self assignment check solves that case, it doesn't solve the exception safety issue. The following implementation solves both problems:
Example &operator=(const Example &other)
{
    int *temp = new int(*other.ptr);
    std::swap(ptr, temp);
    delete temp;
    return *this;
}
Now, this is self assignment safe, but it does unnecessary work in that case. I wouldn't worry about that, self assignment should be rare. I wouldn't "optimise" for that case.

#3 EarthBanana   Members   -  Reputation: 876

Like
1Likes
Like

Posted 07 April 2013 - 09:25 AM

Because the class you are assigning to (the class you are writing the = operator ) typically you first delete the memory used by your members (if you have members that store their memory on the heap ie use new) and then you allocate new memory for your member variables, and then you copy the rhs member variables' contents in to this...

if rhs is *this then you had previously just deleted all of its members



#4 noatom   Members   -  Reputation: 782

Like
0Likes
Like

Posted 07 April 2013 - 10:13 AM

got it,thank you both



#5 iMalc   Crossbones+   -  Reputation: 2301

Like
1Likes
Like

Posted 07 April 2013 - 01:26 PM

Actually, "typicaly" one would use the copy-and-swap idiom, because it is both simpler and exception safe, and does not have any problem with self-assignment.

What is warning you about self-assignment probably only applies in the particular scenario you were reading about. In general there is no reason to. Any assignment operator that must check for self-assignment is not exception safe. See the GotW archives.

Edited by iMalc, 07 April 2013 - 01:27 PM.

"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS