I’ve been reading Myers book and came across the item on returning by reference/pointer vs by value.
The point is, if our function for example is like this:
ClassA& AddSomething(ClassA classA)
{
ClassA tempClassA;
//... do something on tempClassA
return tempClassA;
}
This would not work because we are returning a reference to a object that was created on the stack and it is dead now that the function is done.
He gives two solutions:
- Using a local static ClassA inside the function. This has its
problems but atleast we can be sure that object exists. -
Return as an object:
ClassA AddSomething(ClassA classA) { ClassA tempClassA; //... do something on tempClassA return tempClassA; }
Now if I’m to do:
ClassA obj1;
ClassA obj2 = AddSomething(obj1);
My confusion now is, when executing this line:
- A ‘copy’ of tempClassA is made and passed to the copy constructor
of ClassA (to initialize obj2)? OR - tempClassA is passed itself to the copy constructor of ClassA,
because copy constructor takes a reference.
So basically, whats passed to the copy constructor is a reference to tempClassA (which was created in stack inside the function) or a reference to a copy of tempClassA.
Also, another question I have is, I have read that if I get a reference of a function local variable, in that case the local variable will not be deleted.
For example,
ClassA & classRef = AddSomething(obj1);
In this case, if AddSomething() is returning a reference, then classRef not be pointing to a deleted reference because the local variable will be retained. Have I understood this correctly?
When an object is returned by value, there are two copies taking place: one from the local variable into the return value, and one from the return value into the target object. However, the implementation is allowed to elide one or both of these copies; this is called return value optimisation (RVO) in the first case, and copy elision in the second.
The second function above is a candidate for a refinement type of RVO called named return value optimisation; the simplest form of RVO applies only to return statements that construct the return value inplace.
Regarding your second question, lifetime extension only applies to const references to objects returned by value; your code in the second question will not extend the lifetime of any object. See Returning temporary object and binding to const reference for more details.