
unique ptr
unique_ptr是一种定义在<memory>中的智慧型指针(smart pointer)。它持有对对象的独有权——两个unique_ptr不能指向一个对象,不能进行複製操作只能进行移动操作。
基本介绍
- 外文名:unique ptr
- 类型:智慧型指针
- 定义函式:<memory>
- 所属学科:软体
概要
unique_ptr在超出作用域,即以下情况时它指向的对象会被摧毁:
- unique_ptr指向的对象被破坏
- 对象通过operator=()或reset()被指定到另一个指针)
unique_ptr还可能没有对象,这种情况被称为empty。
例如:
std::unique_ptr<int>p1(new int(5));
std::unique_ptr<int>p2=p1;// 编译会出错
std::unique_ptr<int>p3=std::move(p1);// 转移所有权,那块记忆体归p3所有, p1成为无效的针.
p3.reset();//释放记忆体.
p1.reset();//无效
功能
- 不管是正常退出还是异常退出,均可通过保证删除为处理拥有动态寿命的类和函式提供额外的保护;
- 将独有的持有动态寿命对象传递给函式;
- 从函式获取持有动态寿命对象的所有权
- 所有auto_ptr应该已经具有的功能
unique_ptr十分依赖于右值引用和移动语义。
下面是一段传统的会产生不安全的异常的代码:
X* f() {
X* p =new X; // 做一些事情 – 可能会抛出某个异常
return p;
}
解决方法是,用一个unique_ptr 来管理这个对象的所有权,由其进行这个对象的删除释放工作:
X* f() {
unique_ptr p(new X); // 或者使用{new X},但是不能 = new X
return p.release();
}
如果程式执行过程中抛出了异常,unique_ptr就会(毫无疑问地)删除释放它所指向的对象,这是最基本的RAII。但是,除非我们真的需要返回一个内建的指针,我们可以返回一个unique_ptr,让事情变得更好。
unique_ptr f() {
unique_ptr p(new X); // 或者使用{new X},但是不能 = new X
return p; // 对象的所有权被传递出f()
}
我们可以这样使用函式f():
void g() {
unique_ptr q = f(); // 使用移动构造函式(move constructor)
q->memfct(2); // 使用q
X x = *q; // 複製指针q所指向的对象
// …
} // 在函式退出的时候,q以及它所指向的对象都被删除释放
unique_ptr拥有“移动意义(move semantics)”,所以我们可以使用函式f() 返回的右值对q进行初始化,这样就简单地将所有权传递给了q。
在那些要不是为了避免不安全的异常问题(以及为了保证指针所指向的对象都被正确地删除释放),我们不可以使用内建指针的情况下,我们可以在容器中保存unique_ptr以代替内建指针:
在那些要不是为了避免不安全的异常问题(以及为了保证指针所指向的对象都被正确地删除释放),我们不可以使用内建指针的情况下,我们可以在容器中保存unique_ptr以代替内建指针:
vector<unique_ptr<string>> vs {
new string{"Doug"}, new string{"Adams"}
};
unique_ptr可以通过一个简单的内建指针构造完成,并且与内建指针相比,两者在使用上的差别很小。特殊情况下,unique_ptr并不提供任何形式的动态检查(?)。.
unique_ptr在超出作用域,即以下情况时它指向的对象会被摧毁:
unique_ptr指向的对象被破坏
对象通过operator=()或reset()被指定到另一个指针)
unique_ptr还可能没有对象,这种情况被称为empty。
例如:
std::unique_ptr<int>p1(new int(5));
std::unique_ptr<int>p2=p1;// 编译会出错
std::unique_ptr<int>p3=std::move(p1);// 转移所有权,那块记忆体归p3所有, p1成为无效的针.
p3.reset();//释放记忆体.
p1.reset();//无效