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禁用了拷贝构造和赋值,但提供了交换、移除、转交所有权的接口。
上一篇: 顺序表的实现
推荐阅读
-
unique_ptr功能、源码解析、使用范例
-
android-使用环信SDK开发即时通信功能(附源码下载)
-
Java源码解析ThreadLocal及使用场景
-
Java源码解析阻塞队列ArrayBlockingQueue功能简介
-
Android AsyncTask使用以及源码解析
-
Android AsyncTask使用以及源码解析
-
Android AsyncTask使用以及源码解析
-
OpenFeign---常用功能及源码解析
-
String之PropertyPlaceholderConfigurery源码解析 博客分类: spring PropertyPlaceholderConfigurery源码详解使用
-
使用ajax+php模仿google功能源码