Search code examples
c++referencereturn-value-optimizationreturn-by-reference

C++: returning by reference and copy constructors


References in C++ are baffling me. :)

The basic idea is that I'm trying to return an object from a function. I'd like to do it without returning a pointer (because then I'd have to manually delete it), and without calling the copy-constructor, if possible (for efficiency, naturally added: and also because I wonder if I can't avoid writing a copy constructor).

So, all in all, here are the options for doing this that I have found:

  • The function return type can be either the class itself (MyClass fun() { ... }) or a reference to the class (MyClass& fun() { ... }).
  • The function can either construct the variable at the line of return (return MyClass(a,b,c);) or return an existing variable (MyClass x(a,b,c); return x;).
  • The code that receives the variable can also have a variable of either type: (MyClass x = fun(); or MyClass& x = fun();)
  • The code which receives the variable can either create a new variable on the fly (MyClass x = fun();) or assign it to an existing variable (MyClass x; x = fun();)

And some thoughts on that:

  • It seems to be a bad idea to have the return type MyClass& because that always results in the variable being destroyed before it gets returned.
  • The copy constructor only seems to get involved when I return an existing variable. When returning a variable constructed in the line of return, it never gets called.
  • When I assign the result to an existing variable, the destructor also always kicks in before the value is returned. Also, no copy constructor gets called, yet target variable does receive the member values of the object returned from the function.

These results are so inconsistent that I feel totally confused. So, what EXACTLY is happening here? How should I properly construct and return an object from a function?


Solution

  • The best way to understand copying in C++ is often NOT to try to produce an artificial example and instrument it - the compiler is allowed to both remove and add copy constructor calls, more or less as it sees fit.

    Bottom line - if you need to return a value, return a value and don't worry about any "expense".