1. 几个基本成员函数的作用:
u.reset() 释放u指向的对象
u.reset(q) 如果提供了内置指针q,就令u指向这个对象
u.reset(nullptr) 将 u 置为空
u.release() u 放弃对指针的控制权,返回指针,并将 u 置为空
2. 一些规则:
某个时刻只能有一个unique_ptr 指向一个给定的对象。当它销毁时,它所指向的对象也会被销毁。 初始化 unique_ptr 只能采用直接初始化的方式 (explicit 关键字) 不支持复制构造与赋值操作 在创建或者是reset一个具有删除器的unique_ptr 时,必须提供删除器 不支持拷贝与赋值的规则有一个例外,那就是我们可以拷贝或者赋值一个将要被销毁的unique_ptr(右值引用) ,比如:
unique_ptr<int > clone(int p ){
return unique_ptr<int >(new int (p));
}
unique_ptr<int > clone(int p ){
unique_ptr<int > ret(new int (p));
return ret ;
}
noexcept :在C++11中,声明一个函数不可以抛出任何异常使用关键字noexcept.
3. unique_ptr使用场景
1、为动态申请的资源提供异常安全保证
2、返回函数内动态申请资源的所有权
3、在容器中保存指针
4、管理动态数组
5、作为auto_ptr的替代品
#ifndef _UNIQUE_PTR_H
#define __UNIQUE_H
class Delete {
public :
template <typename T>
void operator ()(T *p) const {
delete p;
}
};
template <typename T,typename D = Delete >
class unique_ptr {
public :
explicit unique_ptr(T *pp = nullptr ,const D &dd= D() )
:un_ptr(pp),del(dd)
{
}
~unique_ptr() {
del(un_ptr);
}
unique_ptr(const unique_ptr&) = delete ;
unique_ptr& operator =(const unique_ptr& ) = delete ;
unique_ptr( unique_ptr&& right_value):
un_ptr(right_value.un_ptr),del(std ::move(right_value.del)) {
right_value.un_ptr = nullptr ;
}
unique_ptr& operator =( unique_ptr&& right_value ) noexcept {
if (this != &right_value ){
std ::cout << "operator && right_value " << std ::endl ;
del(*this );
un_ptr = right_value.un_ptr;
del = std ::move(right_value.del);
right_value.un_ptr = nullptr ;
}
return *this ;
}
T* release(){
T *tmp = un_ptr ;
un_ptr = nullptr ;
return tmp ;
}
void reset(){ del(un_ptr); }
void reset(T* q ){
if ( un_ptr ){
del(un_ptr) ;
un_ptr = q ;
}
else
un_ptr = nullptr ;
}
void swap(unique_ptr &other ) noexcept {
using std ::swap ;
swap( un_ptr,other.un_ptr );
swap(del,other.del) ;
}
T* get() { return un_ptr ; }
D& get_deleter(){ return del ; }
T& operator *() { return *un_ptr ; }
T* operator ->() { return un_ptr ; }
private :
T *un_ptr = nullptr ;
D del ;
};
#endif
#include <iostream>
#include <string>
#include "unique_ptr.h"
#include"DebugDelete.h"
#include <assert.h>
struct Foo {
Foo() { std ::cout << "Foo()\n" ; }
~Foo() { std ::cout << "~Foo()\n" ; }
Foo(const Foo&) { std ::cout << "Foo copy ctor\n" ; }
Foo(Foo&&) { std ::cout << "Foo move ctor\n" ; }
};
struct Fooo {
Fooo(int n = 0 ) noexcept : bar(n) { std ::cout << "Fooo: constructor, bar = " << bar << '\n' ; }
~Fooo() { std ::cout << "Fooo: destructor, bar = " << bar << '\n' ; }
int GetBar() const noexcept { return bar; }
private :
int bar;
};
struct D {
void bar() { std ::cout << "Call deleter D::bar()...\n" ; }
void operator ()(Foo* p) const
{
std ::cout << "Call delete from function object...\n" ;
delete p;
}
};
using namespace std ;
int main()
{
unique_ptr<string > p1(new string ("Shengxi-Liu" ));
cout << *p1 << endl ;
{
std ::cout << "======================\nunique_ptr constructor:\n" ;
unique_ptr<Foo> up1;
unique_ptr<Foo> up1b(nullptr );
unique_ptr<Foo> up2(new Foo);
DebugDelete d;
unique_ptr<Foo, DebugDelete> up3(new Foo, d);
unique_ptr<Foo, DebugDelete&> up3b(new Foo, d);
unique_ptr<Foo, DebugDelete> up4(new Foo, DebugDelete());
unique_ptr<Foo> up5b(std ::move(up2));
unique_ptr<Foo, DebugDelete> up6b(std ::move(up3));
unique_ptr<Foo> up7 = std ::move(up5b);
Foo* fp = up7.release();
assert(up7.get() == nullptr );
delete fp;
up6b.reset(new Foo());
up6b.reset(nullptr );
unique_ptr<Fooo> up71(new Fooo(1 ));
unique_ptr<Fooo> up72(new Fooo(2 ));
up71.swap(up72);
std ::cout << "up71->val:" << up71->GetBar() << std ::endl;
std ::cout << "up72->val:" << (up72.get())->GetBar() << std ::endl;
unique_ptr<Foo, D> up8(new Foo(), D());
D& del = up8.get_deleter();
del.bar();
}
}
参考:https://www.cnblogs.com/DswCnblog/p/5628195.html