先上结论 ^ ^:(如有不对,请指正)
if (定义了 拷贝构造函数 、 拷贝赋值运算符 或 析构函数) {
不会合成移动构造函数和移动赋值运算符。此时会使用对应 拷贝 操作来代替 移动
}
else if (类的所有成员都可以移动) {
则会为类合成移动构造函数或移动赋值运算符。
}
else {
合成拷贝构造函数和拷贝复制运算符。
}
class Test {
public:
Test(int v, const string& str) {
p = new int(v);
s = str;
cout << "test()" << endl;
}
~Test() {
cout << "~Test()" << endl;
delete p;
p = nullptr;
}
private:
int* p = nullptr;
string s;
};
int main() {
Test c(10, "1234");
Test k = std::move(c);
return 0;
}
反汇编:
可见,此时调用Test k = std::move(c);
实际调用的是Test(const Test &);
是copy-construct ;
当然,如果Test定义了Test(const Test& t)
则肯定调用copy-construct ,但是如果定义Test(Test& t)
则会报编译错误。
class Test {
public:
Test(int v, const string& str) {
p = new int(v);
s = str;
cout << "test()" << endl;
}
Test(const Test& t) {
p = new int(*t.p);
cout << "test&" << endl;
}
Test(Test&& t) noexcept {
p = t.p;
t.p = nullptr;
cout << "test&&" << endl;
}
~Test() {
cout << "~Test()" << endl;
delete p;
p = nullptr;
}
private:
int* p = nullptr;
string s;
};
int main() {
Test c(10, "1234");
Test k = std::move(c);
return 0;
}
如果定义了Test(Test&& t)
,则Test k = std::move(c);
肯定调用的是move-construct。
class Test {
public:
Test(int v, const string& str) {
p = new int(v);
s = str;
cout << "test()" << endl;
}
private:
int* p = nullptr;
string s;
};
int main() {
Test c(10, "1234");
Test k = std::move(c);
return 0;
}
这里把析构函数去掉了,此时Test k = std::move(c);
使用了编译器默认生成的move-construct
class NoMove {
public:
NoMove(NoMove&&) = delete;
private:
int i;
};
int main() {
NoMove g; //C2512 “NoMove”: 没有合适的默认构造函数可用
return 0;
}
给NoMove类定义NoMove(NoMove&&) = delete;
以后,NoMove的copy-construct和default-construct被删除,所以报错。
class NoMove {
public:
NoMove() = default;
NoMove(const NoMove&) = default;
NoMove(NoMove&&) = delete;
private:
int i;
};
class Test {
public:
Test(int v, const string& str) {
p = new int(v);
s = str;
cout << "test()" << endl;
}
private:
int* p = nullptr;
string s;
NoMove no;
};
int main() {
Test c(10, "1234");
Test k = std::move(c);
return 0;
}
此时因为NoMove成员没有move-construct,所以Test k = std::move(c);
还是调用了copy-construct.
版权声明:本文为weixin_44240548原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。