可移动构造 可复制构造 可移动赋值 可复制赋值

记录一下这几个容易混淆的概念。

可移动构造(MoveConstructible)

指定该类型的实例可以从一个右值实参构造

定义

给定:

  • T类型的右值表达式rv

  • 任意标识符 u

下列表达式必须合法且拥有指定的效果:

T u = rv;   //u 的值等于 rv 在初始化前的值。rv 的新值未指明。
T(rv); //T(rv) 的值等于 rv 在初始化前的值。rv 的新值未指明。

类不必为满足此要求而实现移动构造函数:接收 const T& 实参的复制构造函数也能绑定右值表达式。

禁用可移动构造
  • 移动构造函数或者移动复制运算符被定义为删除

  • 有类成员为const或引用

  • 定义了自己的拷贝构造函数且未定义移动构造函数,或者有类成员未定义自己的拷贝构造函数且编译器不能为其合成移动构造函数

#include <iostream>
?
using namespace std;
?
class Base
{
int data;
public:
Base(int mdata) : data(mdata){}
int get() { return this->data; }
Base(Base &B)
{
cout << "Base(Base &B)" << endl;
this->data = B.get();
}
Base(Base &&b) = delete;
};
?
Base fun() {
Base b = 1;
return b; //尝试引用已删除的函数
}
?
int main()
{
Base a = 1;
Base b = fun();
?
cout << b.get() << endl;
getc(stdin);
return 0;
}

可复制构造(CopyConstructible)

该类型的实例可以从左值表达式中构造

定义

给定:

  • v为const T或T类型的左值表达式或const T类型的右值表达式

  • 任意标识符u

下列表达式必须合法且拥有其指定的效果

T u = v;    //u的值等价于v的值,不修改v的值
T(v); //同上
禁用

将拷贝构造函数置为delete

可移动赋值(MoveAssignable)

该类型的实例可以从右值实参赋值

定义
t = v;  //t的值等于v的值,v的值不更改,赋值表达式返回(T&)t

对应的是:

Base &operator =(Base &&b)

可复制赋值(CopyAssignable)

该类型的实例可从左值表达式复制赋值

定义
t = v;  //t 的值等价于 v 的值, v 的值不更改。

对应的是:

Base &operator =(Base &b)

 

可移动构造 可复制构造 可移动赋值 可复制赋值

上一篇:Java网络编程:实现HTTP模拟器


下一篇:unia-app页面声明周期