Jump to content

View more

Image of the Day

Adding some finishing touches...
Follow us for more
#screenshotsaturday #indiedev... by #MakeGoodGames https://t.co/Otbwywbm3a
IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.


Sign up now

What is so bad about self-assignment?

4: Adsense

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   

926
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?



#2 rip-off   Moderators   

10923
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   GDNet+   

1792
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   

926
Like
0Likes
Like

Posted 07 April 2013 - 10:13 AM

got it,thank you both



#5 iMalc   Members   

2466
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.