我试图理解 move 构造函数并编写了以下代码
#include<iostream>
#include<string>
using namespace std;
class mystring
{
string s;
public:
mystring(const string& x):
s(x)
{
}
mystring(const mystring& x)
{
cout<<"Copy called"<<endl;
s = x.s;
}
mystring(const mystring&& x)
{
cout<<"Move Called"<<endl;
s = x.s;
}
mystring& operator+(const mystring& x)
{
cout<<"+ operator"<<endl;
s = s+x.s;
return *this;
}
};
int main()
{
string a = "Hello ";
string b = "World ";
mystring a1(a);
mystring b1(b);
mystring c = mystring(a1+b1);
}
我期望在 a1+b1 的结果 rValue 上调用 move 构造函数,但我看到只调用了复制构造函数。我错过了什么吗?
gcc --version
gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
在 HolyBlackCat 的回答后编辑:
#include<iostream>
#include<string>
using namespace std;
class mystring
{
string s;
public:
explicit mystring(const string& x):
s(x)
{
cout<<"ctor called"<<endl;
}
mystring(const mystring& x)
{
cout<<"Copy called"<<endl;
s = x.s;
}
mystring(mystring&& x)
{
cout<<"Move Called"<<endl;
s = std::move(x.s);
}
mystring operator+(const mystring& x) const
{
cout<<"+ operator"<<endl;
return mystring(s+x.s);
}
};
int main()
{
string a = "Hello ";
string b = "World ";
mystring a1(a);
mystring b1(b);
mystring c(a1+b1) ;
}
move 构造函数仍然没有被调用:
ctor called ctor called + operator ctor called
最佳答案
没有理由调用 move 构造函数,因为您的 operator+
不返回临时值。
修改operator+
中的左操作数是个坏主意。没有人期望 a + b
修改 a
。
您应该将其重写为mystring operator+(const mystring& x) const
。这样它确实返回一个临时的,并且应该调用你的 move 构造函数(除非编译器 optimizes it away )。
此外, move 构造函数/赋值的参数通常应该是非const
右值引用。您需要能够修改参数以从中 move 资源。
另外,请注意右值引用是左值。这听起来可能很奇怪,但重点是如果没有 std::move
,即使 x
是 ,
.s = x.s
也会复制字符串>std::string &&
最后, move 构造函数应该是这样的:
mystring(mystring &&x)
{
cout << "Move Called" << endl;
s = std::move(x.s);
}
或者更好,像这样:
mystring(mystring &&x) : s(std::move(x.s))
{
cout << "Move Called" << endl;
}
关于c++ - move 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57344029/