C++移动语义

移动语义

移动语义是C++11引入的一个概念,本质很简单,就是利用右值引用,将资源直接“窃取到自身”,而不是进行深层拷贝。
概念可能有点抽象,我们来看个例子就清楚了。下面的代码中,MyString类中有四个构造函数。前两个都是普通构造函数,重点在后面两个:拷贝构造和移动构造。

class MyString
{
public:
	MyString() = default;
	MyString(const char* string)
	{
		printf("created!\n");
		m_Size = strlen(string);
		m_Data = new char[m_Size];
		memcpy(m_Data, string, m_Size);
	}
	//拷贝构造
	MyString(const MyString& other)
	{
		printf("copied!\n");
		m_Size = other.m_Size;
		m_Data = new char[m_Size];
		memcpy(m_Data, other.m_Data, m_Size);
	}
	//移动构造
	MyString(MyString&& other) noexcept
	{
		printf("moved!\n");
		//仅仅是接管了other的数据,并不像拷贝构造那样还需要分配新的内存来进行深拷贝
		m_Size = other.m_Size;
		m_Data = other.m_Data;
		other.m_Size = 0;
		other.m_Data = nullptr;
	}

	~MyString()
	{
		printf("destroyed!\n");
		delete m_Data;
	}
	
private:
	char* m_Data;
	uint32_t  m_Size;
};
int main(int argc, char* argv[])
{
	std::vector<MyString>   vec;
	MyString   my("xiaoxiaoniao");
	vec.push_back(my);
	//vec.push_back(std::move(my));
}

上面代码中,执行vec.push_back(my)时,会发生什么呢?
啥也不发生,仅仅是将my推入vec中?No,它会创建一个新的MyString对象,将新的对象推入vec中。问题是,会调用哪个构造函数呢?
会调用MyString的拷贝构造函数。而在拷贝构造里,使用new为m_Data重新开辟了堆空间!
但我们回过头来想想,我们仅仅是想把my中的数据放到vec中,为什么还要重新分配堆空间?直接将my中的数据接管过来不可以吗?
当然可以,这就是移动构造!直接接管my对象的数据,然后将my对象中的数据清空,就实现了移动构造。无需重新为MyString类中m_Data重新分配空间,提高了内存的管理效率!

通俗来说,移动构造就像是 没有中间商赚差价了。

当然,我们需要使用std::move函数告知编译器,变量可以当做右值处理,这样才会调用移动构造。
std::move本质其实就是static_cast<decltype(obj)&&>(obj),当然,真实实现要复杂一些。

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值