C++移动构造与std::move()

本文介绍了如何在C++中通过添加移动构造函数和使用std::move来优化MyString类的内存管理,以避免临时变量拷贝带来的空间浪费。作者讨论了移动构造的工作原理、std::move的作用以及在Entity类中的应用,强调了移动构造在提高效率方面的优势。
摘要由CSDN通过智能技术生成

首先推荐好书:

背景及问题

如下程序所示:
#include<iostream>

class MyString {
public:
	MyString() = default;
	MyString(const char* data)
	{		
		printf("%s", "MyString Constructed!!\n");
		size = strlen(data);
		m_data = new char[size];
		memcpy(m_data, data, size);	
	}
	~MyString()
	{
		if (m_data)
		{
			printf("%s", "MyString Destroyed!!\n");
			delete m_data;
		}	
	}
	//copy constructor
	MyString(const MyString& other) noexcept
	{
		printf("%s", "MyString Copyed!!\n");
		size = other.size;
		m_data = new char[size];
		memcpy(m_data, other.m_data, size);
	}

private:
	char* m_data;
	int size;
};

class Entity
{
public:
	//constructor
	Entity(const MyString& string):m_string(string) {}
private:
	MyString m_string;
};

int main()
{	

	Entity entity("Hello");
	return 0;
}

程序说明

程序定义了一个MyString类,其中构造函数和拷贝构造函数需要对传进来的字符串开辟空间并复制内容,另外一个Entity类含有一个MyString成员,并在初始化时复制传入的MyString对象。主程序Main中以常量字符串构造一个entity示例。

image

运行程序会发现,MyString构造了一次,拷贝一次,程序结束析构两次,符合运行逻辑。“Hello”字符串先通过构造函数构造一个临时变量MyString,临时变量再通过Entity内的构造函数拷贝构造给成员变量m_string

问题在于临时变量拷贝构造需要重新开辟空间,并且“用完即扔”,为什么不直接将“hello”构造好的MyString直接“移动”到Entity?这样会节省空间,提高效率。用此引出移动构造和std::move()

移动构造与std::move()

若要实现将临时变量移动到Entity,首先MyString要加入移动构造,如下:
	MyString(MyString&& other) noexcept
	{
		printf("%s", "MyString Moved!!\n");
		size = other.size;
		m_data = other.m_data;

		//clear origin data
		other.size = 0;
		other.m_data = nullptr;
	}

此为移动构造,接受的是一个右值,构造是直接复制原MyString的size与data,不重新开辟空间做深拷贝。并将原MyString清零。接着对Entity构造时使用std::move通知移动构造函数,如下:

	Entity(MyString&& string) :m_string(std::move(string)) {}

image

需要注意的是

1. Entity右值构造时也可不使用std::move,直接将参数强转为右值类型也可以,std::move相当于通知构造函数以移动构造的方式进行
Entity(MyString&& string) :m_string((MyString&&)string) {}

2. 对于形参为Const YourType &类型的既可以接受左值,也可以接受右值。但是使用std::move会编译错误,因为Const值不能被移动,所以Entity构造仍要单独写一个右值构造

3. MyString移动构造时,复制了临时数据的值还要对其清空,因为数据已经被移动,指针没有置空,析构两次会引起Crash问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一百编程网朱老师

谢谢大爷谢谢大爷谢谢大爷谢谢大

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

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

打赏作者

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

抵扣说明:

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

余额充值