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

Posted hadesblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可移动构造 可复制构造 可移动赋值 可复制赋值相关的知识,希望对你有一定的参考价值。

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

可移动构造(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)

 

以上是关于可移动构造 可复制构造 可移动赋值 可复制赋值的主要内容,如果未能解决你的问题,请参考以下文章

如何利用模板复制&移动构造函数和赋值运算符?

memcpy 是可简单复制的类型构造还是赋值?

自动生成默认/复制/移动 ctor 和复制/移动赋值运算符的条件?

5 规则(用于构造函数和析构函数)过时了吗?

❥关于C++之右值引用&移动语义┇移动构造&移动复制

编译器何时不生成移动构造函数和移动赋值?