c++移动构造和普通构造的区别

通过一个例子来说明移动构造和普通构造函数的区别。这个例子也是参考网上的文章做的,原文忘记了。

测试环境:Ubuntu 16.04 LTS

如果一个class动态分配了内存,则普通构造和移动构造有以下区别:

普通构造:会进行深拷贝,涉及到构造和析构

移动构造:不会进行深拷贝,直接对对象的所有权进行转移,效率更高。

下面的示例代码,在generateResource return时,会进行一次拷贝。

如果注释掉移动构造版本的代码,则运行时调用普通的构造函数,log如下:

Auto_ptr3()::=
Resource acquired
Resource ===
~Auto_ptr3()
Resource destroyed

如果打开移动构造版本的代码,则运行时调用移动构造函数,log如下:

Auto_ptr3()::=,move
~Auto_ptr3()

由此可见,如果一个class动态分配了内存,移动构造的效率更高。

/*
	copy constructor
	copy assignment 
	拷贝数据。
	
	move copy constructor
	move copy assignment 
	转移所有权。
*/

#include <iostream>

template<class T>
class Auto_ptr3
{
	T* m_ptr;
public:
	Auto_ptr3(T* ptr = nullptr)
		:m_ptr(ptr)
	{
	    std::cout << "Auto_ptr3()" << std::endl;
	}
 
	~Auto_ptr3()
	{
	    std::cout << "~Auto_ptr3()" << std::endl;
	    delete m_ptr;
	}
 
	// Copy constructor
	// Do deep copy of a.m_ptr to m_ptr
	Auto_ptr3(const Auto_ptr3& a)
	{
		std::cout << "Auto_ptr3()::copy" << std::endl;
		m_ptr = new T;
		*m_ptr = *a.m_ptr;
	}
 
	// Copy assignment
	// Do deep copy of a.m_ptr to m_ptr
	Auto_ptr3& operator=(const Auto_ptr3& a)
	{
		std::cout << "Auto_ptr3()::=" << std::endl;		
		// Self-assignment detection
		if (&a == this)
			return *this;
 
		// Release any resource we're holding
		delete m_ptr;
 
		// Copy the resource
		m_ptr = new T;
		*m_ptr = *a.m_ptr;
 
		return *this;
	}
#if 1
	// Copy constructor
	// move
	Auto_ptr3(Auto_ptr3&& a):m_ptr(a.m_ptr)
	{
		std::cout << "Auto_ptr3()::copy,move" << std::endl;
		a.m_ptr = nullptr;
	}
	
	// Copy assignment
	// move
	Auto_ptr3& operator=(Auto_ptr3&& a)
	{
		std::cout << "Auto_ptr3()::=,move" << std::endl;		
		// Self-assignment detection
		if (&a == this)
			return *this;
 
		// Release any resource we're holding
		delete m_ptr;
 
		// move the ownership
		m_ptr = a.m_ptr;
		a.m_ptr = nullptr;
 
		return *this;
	}
 
	T& operator*() const { return *m_ptr; }
	T* operator->() const { return m_ptr; }
	bool isNull() const { return m_ptr == nullptr; }
#endif
};
 
class Resource
{
public:
	Resource() { std::cout << "Resource acquired\n"; }
	~Resource() { std::cout << "Resource destroyed\n"; }
    Resource& operator=(const Resource& a){ std::cout << "Resource ===\n"; }
private:
	int m_a;
};
 
Auto_ptr3<Resource> generateResource()
{
	/*
		1.new Resource:"Resource acquired"
		2.res(new Resource),执行Auto_ptr3的构造函数:"Auto_ptr3()"
		3.打印“222222222222222”
		4.执行Auto_ptr3的assignment constructor,
		  "Auto_ptr3()::=",
		  "Resource acquired\n",
		  "Resource ===\n"
		5.res析构,~Auto_ptr3()
		  Resource destroyed
	*/
	Auto_ptr3<Resource> res(new Resource);
    std::cout << "222222222222222\n\n";
	return res;  
}
 
int main()
{
	Auto_ptr3<Resource> mainres; // 执行Auto_ptr3的构造函数:"Auto_ptr3()"
	std::cout << "111111111111111\n";
	mainres = generateResource(); // this assignment will invoke the copy assignment
	/* 实际测试发现,函数返回的时候,没有执行copy constructor,而是直接执行的assignment constructor */
	std::cout << "\n3333333333333333\n";
 
	return 0;
}


/*
使用copy constructor和assignment constructor的版本
Auto_ptr3()
111111111111111
Resource acquired
Auto_ptr3()
222222222222222

Auto_ptr3()::=
Resource acquired
Resource ===
~Auto_ptr3()
Resource destroyed

3333333333333333
~Auto_ptr3()
Resource destroyed

使用move的版本
Auto_ptr3()
111111111111111
Resource acquired
Auto_ptr3()
222222222222222

Auto_ptr3()::=,move
~Auto_ptr3()

3333333333333333
~Auto_ptr3()
Resource destroyed
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值