0

Since my copy operator does exactly what I want the assignment operator, to call the copy operator. I've looked at the similar posts I tried creating a new temp object which I called the copy operator on and then returning the temp, but this doesn't work. So I tried sending back a reference but that doesn't work either.

SelfDestructingMessage& SelfDestructingMessage::operator=(
    SelfDestructingMessage &source){
    this(source);
    return *this;
    }

How can I return a reference, not a copy?

2 Answers2

3

You are close. You need a swap so that your assignment operator looks like so:

struct my_object
{
    my_object& operator=(my_object const& other)
    {
        my_object tmp(other);
        swap(*this,other);
        return *this;
    }
 };

You want your swap to be nothrow so that you have exception safety. Note that you can eliminate the name tmp, and maybe allow some significant optimizations, if you just accept the parameter by value.

This is known as the "copy-swap idiom". There are numerous sources but it is best explained in Exceptional C++ by Sutter. He describes it in detail, some variations, and WHY it makes everything easier. When you pair it with pimpl you can gain a huge number of advantages...with some very minor effects on performance in most cases--sometimes it really matters and you can't do a pimpl (pointer indirection can confuse the prefetcher and such).

I don't know WTF Michael Roy is about. I have indeed seen crap like *this = other in the copy constructor but every single dev that has done that also did a lot of other really stupid stuff that ended up giving headaches to way too many people. Just because something is done by some people doesn't mean you need to follow them off a cliff into nonsense.

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
  • I'm running into a "no matching function for call to 'swap(SelfDestructingMessage&, SelfDestructingMessage&)' swap(*this,other); in my cpp file. I've included algorithm using std::swap. Any idea on what caused this? – Seth Killian Jun 21 '17 at 01:24
  • @SethKillian - Yeah, you need to write a swap function. It should perform swap on all its elements. Sorry, thought that was obvious. The constructor performs the work of building the object and swap is responsible for transfering that to yourself. Don't try to call it from the copy constructor please. Your copy constructor, like all constructors should have an empty body. If it's written at all it uses initializer lists. The arguments for this style of coding are numerous and on google and beyond the scope of this answer. Grab the book I recommended. – Edward Strange Jun 21 '17 at 15:35
  • Ah I see. I have it working now. Thanks for the advice - I'll be sure to pick that book up. – Seth Killian Jun 21 '17 at 15:46
-3

You're doing it backwards. The easiest way to reuse object copy code is to call the = operator from the copy constructor.

struct A
{
   A(const A& other) { *this = other; }

   A& operator = (const A& other) { /*....*/ return *this; } 
};

C++ default copy constructors and operators are sufficient in most cases, you should rely on them whenever possible.

Michaël Roy
  • 6,338
  • 1
  • 15
  • 19
  • _"You're doing it backwards."_ - How so? The path the OP is on leads directly to copy & swap which is considered the preferred idiomatic C++ approach to handling this particular problem. – Captain Obvlious Jun 20 '17 at 22:13
  • That's the way it's been done in C++ for ages. Before the age of the forward operator, which is not yet available to all. The question iis: "How can I return a reference, not a copy?" That is not possible if you want to reuse code from the constructor in the copy operator. But is, and has always been possible the other way around. And that's how programmers have done it in the last 30 or so years. – Michaël Roy Jun 20 '17 at 22:32
  • Plus, for the copy and swap idiom you do need a copy constructor, don't you? – Michaël Roy Jun 20 '17 at 22:40
  • 1
    I would say those developers are wrong as are you. Between losing the benefits of the ctor initializer list to the inability to efficiently deal with self assignment there are too many cons to this approach for it to be an effective use of the language.. – Captain Obvlious Jun 20 '17 at 22:43