int i = 10; int & ri = i; int && rri1 = i; // error. i is a lvalue int && rri2 = 10; // true. i is a rvalue int && rri3 = 8 + 10 * i; // true. 8 + 10 * i is a rvalue constint & cri1 = i; // const T&绑定到左值 constint & cri2 = 2 + 3; // const T&绑定到右值
classDad { public: Dad()=default; Dad(const Dad &)=default; Dad(Dad &&)=default; Dad & operator=(const Dad &)=default; Dad & operator=(Dad&&d)=default; ~Dad()=default; public: Son son; Daughter daughter; };
classDad { public: Dad()=default; // Dad(const Dad &)=default; Dad(Dad &&)=default; // Dad & operator=(const Dad &)=default; // Dad & operator=(Dad&&d)=default; // ~Dad()=default; public: Son son; Daughter daughter; };
编译,出现报错:
1 2 3 4 5 6 7 8 9 10
> g++ b.cc -std=c++11 -O2 -o b && ./b b.cc: In function ‘int main()’: b.cc:101:10: error: use of deleted function ‘Dad& Dad::operator=(const Dad&)’ 101 | o2 = o1; | ^~ b.cc:74:7: note: ‘Dad& Dad::operator=(const Dad&)’ is implicitly declared as deleted because ‘Dad’ declares a move constructor or move assignment operator 74 | class Dad | ^~~ b.cc:102:22: error: use of deleted function ‘Dad& Dad::operator=(const Dad&)’ 102 | o2 = std::move(o1);
cout << "========Assign========\n"; Dad o1; Dad o2; o2 = o1; o2 = std::move(o1); return0; }
编译,出现错误(一般IDE也会提示报错而无需编译):
1 2 3 4 5 6 7 8
> g++ b.cc -std=c++11 -O2 -o b && ./b b.cc: In function ‘int main()’: b.cc:101:10: error: use of deleted function ‘Dad& Dad::operator=(const Dad&)’ 101 | o2 = o1; | ^~ b.cc:74:7: note: ‘Dad& Dad::operator=(const Dad&)’ is implicitly declared as deleted because ‘Dad’ declares a move constructor or move assignment operator 74 | class Dad | ^~~
cout << "========Assign========\n"; Dad o1; Dad o2; // o2 = o1; // o2 = std::move(o1); return0; }
编译运行:
1 2 3 4 5 6
/usr/include/c++/11/ext/new_allocator.h:162:11: error: use of deleted function ‘Dad::Dad(const Dad&)’ 162 | { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ b.cc:74:7: note: ‘Dad::Dad(const Dad&)’ is implicitly declared as deleted because ‘Dad’ declares a move constructor or move assignment operator 74 | class Dad | ^~~
同上,提示我们因为Dad类声明了一个移动构造函数或移动赋值运算符,拷贝构造函数被定义为删除。
Verify 3
验证:类成员的移动操作不可见或者被定义为删除时,类的移动操作也被定义为删除
Verify 4
验证:类似拷贝赋值,如果存在类成员是被const修饰的常量或者一个引用,则其移动赋值被定义为删除
为Dad类添加一个int类型常量成员i:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classDad { public: Dad() {} // Dad(const Dad &)=default; // Dad(Dad &&)=default; // Dad & operator=(const Dad &)=default; // Dad & operator=(Dad&&d)=default; // ~Dad()=default; public: constint i{}; Son son; Daughter daughter; };
cout << "========Assign========\n"; Dad o1; Dad o2; // o2 = o1; o2 = std::move(o1); return0; }
编译出错,提示我们移动赋值操作被定义为删除的:
1 2 3 4 5 6 7 8 9
> g++ b.cc -std=c++11 -O2 -o b && ./b b.cc: In function ‘int main()’: b.cc:105:22: error: use of deleted function ‘Dad& Dad::operator=(Dad&&)’ 105 | o2 = std::move(o1); | ^ b.cc:76:7: note: ‘Dad& Dad::operator=(Dad&&)’ is implicitly deleted because the default definition would be ill-formed: 76 | class Dad | ^~~ b.cc:76:7: error: non-static const member ‘const int Dad::i’, cannot use default assignment operator
classDad { public: Dad() : ci(i) {} // Dad(const Dad &)=default; // Dad(Dad &&)=default; // Dad & operator=(const Dad &)=default; // Dad & operator=(Dad&&d)=default; // ~Dad()=default; public: int & ci; Son son; Daughter daughter; };
编译器提示的错误信息如下:
1 2 3 4 5 6 7 8 9
> g++ b.cc -std=c++11 -O2 -o b && ./b b.cc: In function ‘int main()’: b.cc:105:22: error: use of deleted function ‘Dad& Dad::operator=(Dad&&)’ 105 | o2 = std::move(o1); | ^ b.cc:76:7: note: ‘Dad& Dad::operator=(Dad&&)’ is implicitly deleted because the default definition would be ill-formed: 76 | class Dad | ^~~ b.cc:76:7: error: non-static reference member ‘int& Dad::ci’, cannot use default assignment operator