欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-02-29 08:24:46
...

一、概述

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禁用了拷贝构造和赋值,但提供了交换、移除、转交所有权的接口。