str2 = String(str);
Let's analyze this line. What happens here is the following:
- A temporary object is created that will be a copy of
str
(hence the copy constructor is called).
- The assignment operator is then called, in charge of copying the information of said temporary object to
str2
.
- Finally the temporary object is destroyed since the execution leaves its scope.
An example to make it look a little clearer:
class String{
public:
String(const char *str = " ")
{ std::cout << "String::String(const char*)\n"; }
~String()
{
std::cout << "String::~String()\n";
}
String(const String &obj)
{
std::cout << "String::String(String)\n";
}
String& operator=(const String& obj)
{
std::cout << "String::operator=(String)\n";
return *this;
}
friend istream& operator >> (istream &input, String &obj);
friend ostream& operator << (ostream &input, const String &obj);
};
int main()
{
std::cout << "Creacion objeto str\n";
String str = String();
std::cout << "Creacion objeto str2\n";
String str2(str);
std::cout << "Creacion objeto str3 (copia temporal)\n";
String str3;
str3 = String(str);
std::cout << "Asignacion str2=str\n";
str2 = str;
std::cout << "Liberacion de recursos\n";
return 0;
}
The output of this example is as follows:
Creacion objeto str
String::String(const char*)
Creacion objeto str2
String::String(String)
Creacion objeto str3 (copia temporal)
String::String(const char*)
String::String(String)
String::operator=(String)
String::~String()
Asignacion str2=str
String::operator=(String)
Liberacion de recursos
String::~String()
String::~String()
String::~String()
That explained in detail would look like this:
Creacion objeto str
String::String(const char*) // 1
Creacion objeto str2
String::String(String) // 2
Creacion objeto str3 (copia temporal)
String::String(const char*) // 3
String::String(String) // 4
String::operator=(String) // 5
String::~String() // 6
Asignacion str2=str
String::operator=(String) // 7
Liberacion de recursos
String::~String() // 8
String::~String() // 9
String::~String() // 10
str
is created. This constructor is called because it has values because, despite having an argument, the declaration is assigned one by default. For this reason it replaces the default constructor
The copy constructor is called to create str2
The str3
object is created. Same case as in (1)
The temporary object is created from str
The content of the temporary object is copied to str3
The temporary object is destroyed
Copy of the content of str
in str2
Destruction of str3
Destruction of str2
Destruction of str
EDITO :
Why is not the constructor copied from str2
directly from the line that opens this answer?
The reason is that, in that line, str2
has already been built and C ++ will not call the constructor copy on its own (among other things because that could lead to stability problems when leaving resources without releasing ).
Having said that, in C ++ there are two ways to call the copy constructor:
String str2(str);
String str2 = String(str);
Being, in this case, the second option is more recommendable since the first one could be confused with the declaration of a function. In fact in C ++ 11 the correct thing would be to do the following:
String str2{str};
But beware, the following code is not going to call the copy constructor that we expect, but will involve the creation of a temporary object:
String str2;
str2 = String(str);
In this case, the ideal thing would be to do the following:
String str2;
str2 = str;
Because this way, at least, we avoid a construction and an erasure.