Reputation: 35
I am trying to call the move constructor but the copy constructor is getting called. What am I doing wrong?
#include <iostream>
#include <string.h>
class X
{
char* name;
public:
X(const char* p)
{
name = new char[strlen(p) + 1];
strcpy(name, p);
std::cout<<"Constructor: "<<name<<"; Address: "<<this<<std::endl;
}
~X()
{
std::cout<<"Destructor: "<<name<<"; Address: "<<this<<std::endl;
delete [] name;
}
X(const X& a)
{
name = new char[strlen(a.name) + 1];
strcpy(name, a.name);
std::cout<<"Copy Constructor: "<<name<<"; Address: "<<this<<"; made from: "<<&a<<std::endl;
}
X& operator=(const X& a)
{
if (name)
{
delete [] name;
}
name = new char[strlen(a.name) + 1];
strcpy(name, a.name);
std::cout<<"Assignment operator: "<<name<<"; Address: "<<this<<"; made from: "<<&a<<std::endl;
return *this;
}
X operator+(const X& a)
{
std::string s1 = name;
std::string s2 = a.name;
s1.append(" ");
s1.append(s2);
X x(s1.c_str());
std::cout<<"operator+: "<<s1.c_str()<<"; Address: "<<&x<<"; Created from"
<<this<<" and "<<&a<<std::endl;
return x;
}
// move copy constructor
X(X&& a)
{
name = a.name;
a.name = nullptr;
std::cout<<"Move Copy Constructor: "<<name<<"; Address: "<<this<<std::endl;
}
friend X fun(const X& a);
};
X fun(const X& a)
{
std::cout<<"Inside fun()"<<std::endl;
X p = a;
return p;
}
int main()
{
X h("Harry");
X r("Ron");
std::cout<<"Trying to create a temporary object"<<std::endl;
X a = fun(h + r);
std::cout<<"Check above if a temporay object was created"<<std::endl;
return 0;
}
O/P of the above program:
Constructor: Harry; Address: 0x79315dbc31b0
Constructor: Ron; Address: 0x79315dbc31c0
Trying to create a temporary object
Constructor: Harry Ron; Address: 0x79315dbc31e0
operator+: Harry Ron; Address: 0x79315dbc31e0; Created from0x79315dbc31b0 and 0x79315dbc31c0
Inside fun()
Copy Constructor: Harry Ron; Address: 0x79315dbc31d0; made from: 0x79315dbc31e0
Destructor: Harry Ron; Address: 0x79315dbc31e0
Check above if a temporay object was created
Destructor: Harry Ron; Address: 0x79315dbc31d0
Destructor: Ron; Address: 0x79315dbc31c0
Destructor: Harry; Address: 0x79315dbc31b0
Does it mean the program is not able to create a temporary object? I thought the object with address 0x79315dbc31e0 was a temporary object.
Note: Since my gcc is old I tried this code on one of the online C++ compilers that support C++11 and C++14.
Upvotes: 0
Views: 398
Reputation: 118302
The call to the "Copy Constructor", immediately after "Inside fun()", is actually the call to the copy constructor from the following line, in fun()
:
X p = a;
That's the call to the copy constructor. You were obviously expecting a move constructor to be invoked as a result of:
X a = fun(h + r);
This temporary is completely "elided" away. This entire sequence:
X p = a;
return p;
Results in the compiler essentially constructing p
as the return value from the function, so "return p" does nothing.
Then, because the return value from the function gets used to instantiate the a
object in main(), the caller essentially passes main()'s "a", to fun()
, as the object to be constructed by fun()
.
You can see for yourself, the sequence of these events, simply by stepping through your code with the debugger.
Upvotes: 2