C++ 移动构造和拷贝构造函数匹配
既有拷贝构造又有移动构造
这个比较好理解,普通的函数匹配规则就可以。右值移动,左值拷贝。 ——《C++ Primer》 P477
我们不能隐式地将一个右值引用绑定到一个左值。
有拷贝构造但没有移动构造
这种情况,右值也会被拷贝。
如果一个类没有移动构造函数,函数匹配规则保证该类型的对象会被拷贝,即使我们试图通过调用 move 来移动它们时也是如此。
因为我们可以将一个 Foo&&
转换为一个 const Foo&
。因此,调用拷贝构造函数是可行的。
要有一个意识:不管左值引用还是右值引用,它们都是引用。
拷贝并交互赋值运算符和移动操作
此运算符有一个非引用参数,这意味着此参数要进行拷贝初始化。——《C++ Primer》 P478
//赋值运算符既是移动赋值运算符,也是拷贝赋值运算符
HasPtr& operator=(HasPtr rhs) {
swap(*this,rhs);return *this;
}
只有移动构造和移动赋值运算符
这样合成的拷贝构造和拷贝赋值会默认定义为删除的,类对象不能进行正常的拷贝操作。
class Dog
{
public:
Dog() = default;
Dog(Dog &&d)
{
a = d.a;
}
Dog & operator=(Dog &&d)
{
a = d.a;
}
private:
int a{ 100 };
};
int main()
{
Dog d1;
Dog d2 = d1; // 报错:拷贝构造函数默认删除
Dog d3;
d3 = d1; // 报错:拷贝赋值运算符被删除
system("pause");
return EXIT_SUCCESS;
}
可以结合,C++ 模板实参推断和引用折叠和C++ 模板参数的两种类型转换来理解。