why copy constructor is called when we return an object from a method by value. please see my below code in that i am returning an object from a method while returning control is hitting the copy constructor and then returning. i am not understood following things:
1) why it is calling copy constructor.
2)which object is passing implicitly to copy constructor,
3)to which object copy constructor will copy the content,
4)what is the necessity of copying the object content while returning. so plz help.
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
class ClassA
{
int a, b;
public:
ClassA()
{
a = 10;
b = 20;
}
ClassA(ClassA &obj)
{
cout << "copy constructor called" << endl;
}
};
ClassA function (ClassA &str)
{
return str;
}
int main ()
{
ClassA str;
function(str);
//function(str);
return 0;
}
object
str
will copy-constructored in a temporary object with typeClassA
for further usage. However compiler can omit it due to optimization.The function returns an object. Hence, that object must exist. Hence, that object must be created from somewhere. Clearly this means that one of its constructors shall be used. The question is, which one?
Since you chose to
return str;
, this is the instruction that shall be used to create it. How else could you use that return instruction to create and return an object and yet not use the copy constructor? It is clear that you need to usestr
to initialize the returned value, so you're not going to use the other option (the parameterless constructor).I'll try to answer all the questions at once.
The behavior you are observing is due to the way returning an object by value works in C++. First, a temporary object is copy-constructed (or move-constructed, in C++11) from the value returned by your function. Then, if this return value is used to initialize another object, such as in:
The object
c
is copy-constructed (or move-constructed, in C++11), from that temporary.This said, an implementation is allowed to elide one (in your concrete case) or both of these calls to the copy or move constructor per paragraph 12/8.31 of the C++11 Standard even though those constructors have side effects, and construct the function's return value directly in
c
:The reason why I wrote that in your specific case only one of the calls to the copy or move constructor can be elided is the sentence in bold in the first bullet of the Standard quote above:
If you are returning a parameter of your function, copy elision is inhibited.
Also notice, that the signature of your constructor should be:
There is no reason for you to accept an lvalue reference to non-
const
in the copy constructor, since you are not going to modify the object you are copying from.Even worse, the above would prevent copy construction from rvalues (like temporaries), so the following code would not compile:
Even though an implementation is allowed to elide the copy, a viable and accessible copy constructor (or move constructor, if we're talking about a move) should still be present.
The copy constructor is called because you call by value not by reference. Therefore a new object must be instantiated from your current object since all members of the object should have the same value in the returned instance. Because otherwise you would be returning the object it self, which would be returning by reference. In this case modifying the reference object would change the original as well. This is generally not a behavior one wants when returning by value.