我正在尝试调用move构造函数,但是调用了复制构造函数。 我做错了什么?
#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:
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
是否意味着程序无法创建临时对象? 我以为地址为0x79315dbc31e0的对象是一个临时对象。
注意:由于我的gcc已经老了,我在其中一个支持C ++ 11和C ++ 14的在线C ++编译器上尝试了这段代码。
答案 0 :(得分:2)
在“Inside fun()”之后立即调用“复制构造函数”实际上是从fun()
中的以下行调用复制构造函数:
X p = a;
这是对复制构造函数的调用。您显然期望由于以下原因而调用移动构造函数:
X a = fun(h + r);
这个临时性被完全“消除”了。整个序列:
X p = a;
return p;
结果在编译器中基本上构造p
作为函数的返回值,因此“return p”什么都不做。
然后,因为函数的返回值用于实例化main()中的a
对象,所以调用者实际上将main()的“a”传递给fun()
,作为由fun()
构建的对象。
只需使用调试器逐步执行代码,就可以亲眼看到这些事件的顺序。