是时候来点现代c++了 c++11重要新特性之move semantic详细解析(也就是移动语义啦)

在说移动语义之前 本文作者假设你已经具备了深拷贝浅拷贝左值右值等基本概念 本文不会再过多叙述 那么接下来 让我们开始吧

Tips:(警告 警告 警告 警告)在阅读本文章之前 作者首先提醒 线代编译器有RVO和NRVO等一系列优化策略 除非你明确知道你要使用std::move 不然我并不是很推荐你使用移动语义 他很有可能是无意义的

在说移动语义之前 让我们先来说说移动构造这玩意

我们都知道 深拷贝是会把在堆区的内存一起拷贝的 那么如果我们明确知道一个对象并不会再继续使用 但是同时我们又想拿到他堆区的资源的时候 我们应该怎么办呢? 移动构造给我们提供了这种能力 代码如下所示:

class MoveClass
{
public:
	int* p;
	MoveClass()
	{
		p = new int();
		std::cout << "默认构造调用" << std::endl;
	}
	~MoveClass()
	{
		std::cout << "析构函数调用" << std::endl;
		if (!p)
			delete p;
	}
	MoveClass(MoveClass& tmp)
	{

	}
	 MoveClass(MoveClass&& tmp)
	{
		std::cout << "移动构造函数调用" << std::endl;
		this->p = tmp.p;
		tmp.p = nullptr;
	}
	MoveClass& operator=(MoveClass&& tmp)
	 {
		 std::cout << "移动构造函数调用" << std::endl;
		 this->p = tmp.p;
		 tmp.p = nullptr;
	 }
};
MoveClass MoveClassTest(MoveClass d)
{
	return MoveClass();
}
int main()
{
	MoveClass cc;
	//好 接下来我们不再想使用c了 但是堆区的资源我们并不想拷贝 那么使用如下构造方式
	MoveClass d(std::move(cc));
	system("pause");
}

移动前数据如下图所示:

移动后数据如下图所示:

 

 程序输出结果:

 

为什么我们需要move semantic?

 设想一个场景 我们在一个作用域申请了一个超级大的string 如下图所示

#include <iostream>
#include <string.h>
void test1(std::string s)
{
	std::cout << "test1:" << s.c_str()<<std::endl;;
}
void test()
{
	std::string s = "超级大的string";
	test1(s);
	std::cout <<"test:"<< s.c_str() << std::endl;
	return;
}
int main()
{
	test();
	system("pause");
}

运行结果如下:

你们就要说了 有啥用啊 但是只要你懂一点c++ 你就会知道 在test中的s我们是不需要了的 也就是我们在test是不想再继续使用s的 但是在我们调用test1的时候 我们又重新拷贝了s一份 那么性能是不是就浪费了呢?如果这个string超级大 你的程序是不是就很垃呢 

我们只需要简简单单的加一个std::move 他就不是拷贝 而只是单纯的移动指针 如下

#include <iostream>
#include <string.h>
void test1(std::string s)
{
	std::cout << "test1:" << s.c_str()<<std::endl;;
}
void test()
{
	std::string s = "超级大的string";
	test1(std::move(s));
	std::cout <<"test:"<< s.c_str() << std::endl;
	return;
}
int main()
{
	test();
	system("pause");
}

运行结果如下: 

 

这就是他最最最本质的作用 一个东西是左值时 你仍然想要他去触发移动构造 记住 其他时候你并不需要去考虑 因为编译器有优化懂吗 不要尝试自己去干扰编译器的优化 除非你真的非常非常非常清楚你自己正在干什么

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杀神李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值