unique_ptr功能、源码解析、使用范例

一、概述

unique_ptr用于管理对象,实现对象的自动释放,它不能被拷贝或赋值,保证了指针只被它管理,提供了接口转移拥有权。

二、使用示例

#pragma once
#include <memory>
#include <string>
#include <iostream>
using namespace std;
class PtrClass
{
    
    
private:
	string s;
public:
	PtrClass(string s)
	{
    
    
		this->s = s;
		cout << "create " << s << endl;
	}
	~PtrClass()
	{
    
    
		cout << "dispose " << s << endl;
	}

};
class UniquePtrTest
{
    
    
public:
	void doTest()
	{
    
    
		shared_ptr<PtrClass> sharedPtr1(new PtrClass("shared1"));
		unique_ptr<PtrClass> uniquePtr1(new PtrClass("unique1"));
		unique_ptr<PtrClass> uniquePtr2;
		uniquePtr2.reset(new PtrClass("unique2"));

		uniquePtr2.swap(uniquePtr1); //交换关系
		//unique_ptr<PtrClass> uniquePtr3 = uniquePtr1; //会编译错误
		uniquePtr2.release(); //释放uniquePtr2对对象的管理权,会导致unique1对象不被delete,内存泄露

		shared_ptr<PtrClass> sharedPtr3 = sharedPtr1;

	}
};

三、输出

create shared1
create unique1
create unique2
dispose unique2
dispose shared1

四、unique_ptr主要源码

template<class _Ty,	class _Dx>	class unique_ptr
	: public _Unique_ptr_base<_Ty, _Dx>
{
    
    	// non-copyable pointer to an object
public:
	typedef unique_ptr<_Ty, _Dx> _Myt;
	typedef _Unique_ptr_base<_Ty, _Dx> _Mybase;
	typedef typename _Mybase::pointer pointer;
	typedef _Ty element_type;

	constexpr unique_ptr() _NOEXCEPT
		: _Mybase(pointer())
	{
    
    	// default construct
		static_assert(!is_pointer<_Dx>::value,
			"unique_ptr constructed with null deleter pointer");
	}

	constexpr unique_ptr(nullptr_t) _NOEXCEPT
		: _Mybase(pointer())
	{
    
    	// null pointer construct
		static_assert(!is_pointer<_Dx>::value,
			"unique_ptr constructed with null deleter pointer");
	}

	_Myt& operator=(nullptr_t) _NOEXCEPT
	{
    
    	// assign a null pointer
		reset();
		return (*this);
	}

	explicit unique_ptr(pointer _Ptr) _NOEXCEPT
		: _Mybase(_Ptr)
	{
    
    	// construct with pointer
		static_assert(!is_pointer<_Dx>::value,
			"unique_ptr constructed with null deleter pointer");
	}

	unique_ptr(unique_ptr&& _Right) _NOEXCEPT //提供了移动拷贝函数
		: _Mybase(_Right.release(),
			_STD forward<_Dx>(_Right.get_deleter()))
	{
    
    	// construct by moving _Right
	}


	_Myt& operator=(_Myt&& _Right) _NOEXCEPT //提供了移动赋值函数
	{
    
    	// assign by moving _Right
		if (this != &_Right)
		{
    
    	// different, do the move
			reset(_Right.release());
			this->get_deleter() = _STD forward<_Dx>(_Right.get_deleter());
		}
		return (*this);
	}

	void swap(_Myt& _Right) _NOEXCEPT //交换所有权
	{
    
    	// swap elements
		_Swap_adl(this->_Myptr(), _Right._Myptr());
		_Swap_adl(this->get_deleter(),
			_Right.get_deleter());
	}

	~unique_ptr() _NOEXCEPT
	{
    
    	// destroy the object
		if (get() != pointer())
			this->get_deleter()(get());
	}

	typename add_lvalue_reference<_Ty>::type operator*() const
	{
    
    	// return reference to object
		return (*get());
	}

	pointer operator->() const _NOEXCEPT
	{
    
    	// return pointer to class object
		return (pointer_traits<pointer>::pointer_to(**this));
	}

	pointer get() const _NOEXCEPT
	{
    
    	// return pointer to object
		return (this->_Myptr());
	}

	pointer release() _NOEXCEPT //移除所有权
	{
    
    	// yield ownership of pointer
		pointer _Ans = get();
		this->_Myptr() = pointer();
		return (_Ans);
	}

	void reset(pointer _Ptr = pointer()) _NOEXCEPT //修改所有权
	{
    
    	// establish new pointer
		pointer _Old = get();
		this->_Myptr() = _Ptr;
		if (_Old != pointer())
			this->get_deleter()(_Old);
	}

	unique_ptr(const _Myt&) = delete; //禁用拷贝构造
	_Myt& operator=(const _Myt&) = delete; //禁用普通赋值
};

五、unique_ptr源码分析

unique_ptr禁用了拷贝构造和赋值,但提供了交换、移除、转交所有权的接口。

猜你喜欢

转载自blog.csdn.net/gamekit/article/details/107421702