前言
从C++智能指针——auto_ptr详解中可以了解到auto_ptr指针的特性以及在C++11中已经被unique_ptr所代替。
unique_ptr介绍
与auto_ptr相比unique_ptr有如下特点:
1、 unique_ptr是一个独享所有权的智能指针,无法进行复制构造、赋值操作操作,只能进行移动操作。无法使两个unique_ptr指向同一个对象;
2、unique_ptr智能指向一个对象,如果当它指向其他对象时,之前所指向的对象会被摧毁。
3、unique_ptr对象会在它们自身被销毁时使用删除器自动删除它们管理的对象。
4、unique_ptr支持创建数组对象方法。
unique_ptr详解
定义:
// non-specialized
template > class unique_ptr;
// array specialization
template class unique_ptr;
上述定义中 T 指其管理的对象类型,D 指该对象摧毁时所调用的释放方法,可以使用自定义的删除器,他也有一个默认的实现。
使用介绍
1、unique_ptr跟auto_ptr创建的方法一样。
// unique_ptr constructor example
#include
#include
int main () {
std::default_delete d;
std::unique_ptr u1;
std::unique_ptr u2 (nullptr);
std::unique_ptr u3 (new int);
std::unique_ptr u4 (new int, d);
std::unique_ptr u5 (new int, std::default_delete());
std::unique_ptr u6 (std::move(u5));
std::unique_ptr u7 (std::move(u6));
std::unique_ptr u8 (std::auto_ptr(new int));
std::cout << "u1: " << (u1?"not null":"null") << '\n';
std::cout << "u2: " << (u2?"not null":"null") << '\n';
std::cout << "u3: " << (u3?"not null":"null") << '\n';
std::cout << "u4: " << (u4?"not null":"null") << '\n';
std::cout << "u5: " << (u5?"not null":"null") << '\n';
std::cout << "u6: " << (u6?"not null":"null") << '\n';
std::cout << "u7: " << (u7?"not null":"null") << '\n';
std::cout << "u8: " << (u8?"not null":"null") << '\n';
return 0;
}
输出:
u1: null
u2: null
u3: not null
u4: not null
u5: null
u6: null
u7: not null
u8: not null
unique_ptr中不能执行copy构造函数和赋值函数原因是在代码中有如下声明:
// Disable copy from lvalue.
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;
2、析构函数
// Destructor.
~unique_ptr() { reset(); }
析构函数中调用了reset函数,而reset函数的主要作用就是销毁当前由unique_ptr(如果有)管理的对象并取得p的所有权。如果p是空指针(例如默认初始化指针),则unique_ptr变为空,在调用后不管理任何对象。
ps:这里的p其实指的就是unique_ptr构造函数中class T的对象。
3、reset函数
reset函数的主要作用就是销毁当前由unique_ptr(如果有)管理的对象并取得p的所有权。具体实例:
// unique_ptr::reset example
#include
#include
int main () {
std::unique_ptr up; // empty
up.reset (new int); // takes ownership of pointer
*up=5;
std::cout << *up << '\n';
up.reset (new int); // deletes managed object, acquires new pointer
*up=10;
std::cout << *up << '\n';
up.reset(); // deletes managed object
return 0;
}
输出:
5
10
4、release函数
该函数负责释放当前管理对象的指针(即unique_ptr中class T的对象),具体使用:
// unique_ptr::release example
#include
#include
int main () {
std::unique_ptr auto_pointer (new int);
int * manual_pointer;
*auto_pointer=10;
manual_pointer = auto_pointer.release();
// (auto_pointer is now empty)
std::cout << "manual_pointer points to " << *manual_pointer << '\n';
delete manual_pointer;
return 0;
}
输出:
manual_pointer points to 10
5、get函数
返回存储的指针。
std::unique_ptr foo(new int(22));
int * p = 0;
p = foo.get(); //p指向的对象为22
6、该指针通常都是默认的删除器,不支持删除数组和不是new出来的指针,具体原因和shared_ptr一样。
扩展
unique_ptr出了上述自己实现的方法外,C++ 提供了一个 move() 库函数,可用于将对象的所有权从一个独占指针转移到另外一个独占指针。
通过move方法可以让unique_ptr被当成参数传递到方法内部,而不用担心所有权被转移而无法继续使用的问题。
std::unique_ptr foo(new int(22));
std::unique_ptr bar = std::move(foo); // foo null, bar 22
参考:http://www.cplusplus.com/reference/memory/unique_ptr/
unique_ptr源码