c++移动语义(std::move)

c++11 引入了左值,右值,移动构造函数,移动赋值函数等新概念,其实都是为了支持移动语义而引入的

c++11引入了左值和右值的概念:

  1. 左值:能取使用&获取到地址的都为左值
  2. 右值:不能获取地址的为右值,匿名变量一律为右值
  3. std::move()函数将左值转化成右值
  4. 右值引用主要用于移动语义(move)和完美转发

 

移动构造函数的功能:

1.移动构造函数一般是在类中需要深拷贝(即成员变量含有指针类型,内容存放在堆中)的时候才需要用,移动构造函数的功能跟拷贝构造函数的功能类似,有一点不同的是,在拷贝构造函数中实现深拷贝的内容,在移动构造函数中直接把原对象的指针直接赋值给新的对象(没有重新在堆中申请内存然后把原对象的内容拷贝过来,而是直接使用原对象的内存地址),然后将原对象的指针置为NULL(避免在原对象析构时把这段内容释放掉,delete NULL这样的操作也不会出问题)

2.移动构造函数优先规则:当类中同时包含移动构造函数和拷贝构造函数时,如果使用临时对象初始化当前类的对象,编译器会优先使用移动构造函数来完成此操作。只有当类中没有移动构造函数时,才会选择拷贝构造函数来完成。

3.如果使用左值来构造新的对象,但是又想调用移动构造函数来完成,那么就可以使用std::move()函数来将左值转化成右值,然后编译器就会选择移动构造函数来完成这个拷贝操作

下面是示例代码

#include <iostream>
#include <vector>
#include <set>
#include <string>
#include <algorithm>
#include <map>
#include <unordered_map>
#include <queue>
#include <list>
#include <stack>
using namespace std;

class A {
public:
	A(int i, std::string str):i(i){
		len = str.size() + 1;
		p = new char[len]{ 0 };
		memcpy(p, str.c_str(), str.size());
		cout << "construct" << endl;
	}
	A() = default;
	A(const A& a)//拷贝构造函数(深拷贝)
		:p(new char[len])
	{
		memcpy(p, a.p, len);
		len = a.len;
		cout << "copy construct" << endl;
	}
	A(A &&a)//移动构造函数
	{
		i = a.i;
		p = a.p;
		len = a.len;
		a.len = 0;
		a.p = NULL;//然后再将指针置为NULL
		cout << "move construct" << endl;
	}
	~A()
	{
		delete p;
		cout << "destruct" << endl;
	}
public:
	int i = 0;
	int len = 0;
	char *p = NULL;
};


int main(int argc, char** argv)
{
	A a(4, "hahahh");
	printf("a.p=%x\n", a.p);
	A b(std::move(a)); //通过使用std::move函数将左值a转换成右值,调用移动构造函数
	
	printf("a.i=%d a.p=%x b.i=%d b.p=%x\n", a.i, a.p, b.i, b.p);
	A c(b); //b是左值,只能调用拷贝构造函数
	return 0;
}

以上程序输出为:

construct
a.p=9cfed40
move construct
a.i=4 a.p=0 b.i=4 b.p=9cfed40
copy construct
destruct
destruct
destruct

参考文章:

http://c.biancheng.net/view/7847.html

https://blog.csdn.net/p942005405/article/details/84644069/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值