Sign in to follow this  
noatom

What is so bad about self-assignment?

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this