With the following code:
class C { ... } c1;
C func(C& ref)
{
// función que devuelve un objeto
...
return ref;
}
...
{
...
c2 = func(c1);
}
When a function returns an object it's another alternative to using the copy constructor, but can someone explain exactly when the copy is created?
Because on the one hand, the function that I have put creates a reference to the c1
. So you work with it, and just when it happens return ref;
is when the copy constructor is called to copy ref
? Or does it do it when you exit the function func
and it happens func(c1);
and after that temporary copy is already assigned with the operador=()
a c2
?
Thank you!
No. The function
func
receives a reference to an object that exists in another context, there is no object creation there.Correct, the return of
func
isC
, in other words " The functionfunc
returns an instance of typeC
"; the only way to return an instance is to create it.Testing the code.
If we add some chivatos to the object
C
we can see its behavior:The above code produces the following output :
0x6013d1
) corresponds to the instancec1
in global space; by staying in global space it is created before the call tomain
(and possibly because of that it has another kind of memory address, but that's implementation dependent).main
.c1
is passed tofunc
without causing any object copies (if so, the copy constructor flag would have been seenC::C(const C&)
before enteringfunc
).0x7ffec496789f
) insidefunc
copyingc1
and we return tomain
storing the previously created object inc2
.main
.c2
(0x7ffec496789f
) for going out of scope ofmain
.c1
(0x6013d1
) because aftermain
it the automatic memory is freed.Return Value Optimization (OVR).
C++ compilers can avoid copying return objects into a function if they infer that the program will behave the same way by constructing the object directly outside the function. Let's change the test code to demonstrate it:
The above code produces the following output :
func
before thanmain
to initialize the objectc1
.c1
(0x6013d1
) in the global space.main
.func
From is called tomain
initialize the objectc2
.c2
( ) is constructed0x7ffc46cb975f
in the scope ofmain
.main
.c2
(0x7ffc46cb975f) for going out of scope ofmain
.c1
(0x6013d1) because after thatmain
the automatic memory is freed.It is noteworthy that the copy constructor
C
has not been called even once even though itfunc
returns instances ofC
. This is because the compiler has applied OVR by detecting that the return offunc
could be constructed directly at the call point instead of creating the object inside and copying it out.In versions prior to C++17 you can disable OVR by configuring the compiler properly, but starting with C++17 OVR is guaranteed at the standard level (my translation and highlighting):