C++ | unique_ptr
unique_ptr
一个unique_ptr独占它所指向的对象。当unique_ptr被销毁时,它所指向的对象也被销毁。
初始化unique_ptr时只能使用直接初始化的方式,不能使用普通的拷贝或赋值操作。
unique_ptr<string> p1; //正确 unique_ptr<int> p2(new int(9)); //正确 unique_ptr<string> p3(new string("DAYH")); //正确 unique_ptr<string> p4(p3); //错误:unique_ptr不支持拷贝 unique_ptr<string> p5; p5 = p4; //错误:unique_ptr不支持赋值
unique_ptr的一些操作。
unique_ptr<T> p | 空只能指针,可以指向类型为T的对象,用delete释放对象资源 |
unique_ptr<T,D> p | 空只能指针,可以指向类型为T的对象,用类型为D的可调用函数释放对象资源 |
unique_ptr<T,D> p(d) | 空只能指针,可以指向类型为T的对象,用类型为D的对象d代替delete |
p | if(p),若p指向一个对象,表达式为true |
*p | 解引用 |
p->attr | 等价于(*p).attr |
p->get() | 返回p中保存的指针 |
swap(p,q) | 交换p和q中的指针 |
p.swap(q) | 交换p和q中的指针 |
p = nullptr | 释放p指向的对象,将p置空 |
p.release() | p放弃对指针的控制权,返回指针,并将p置空 |
p.reset() | 释放p指向的对象 |
p.reset(q) | 提供内置指针q,将p指向这个对象,否则将p置空 |
p.reset(nullptr) |
unique_ptr不能赋值和拷贝,但可以通过调用release()和reset()来转移对象控制权。
unique_ptr<int> p2(p1.release()); // release将p1置空,同时将对象所有权转移给p1 unique_ptr<int> p3(new int(9)); // 将所有权从p3转移给p2 p2.reset(p3.release()); // reset释放了p2原来的内存
release()返回unique_ptr当前保存的指针并将其置空。因此,p2被初始化为p1原来保存的指针,而p1被置空。
reset()令unique_ptr重新指向给定的指针。如果unique_ptr不为空,它原来的对象被释放。因此p2调用reset()释放了用p1初始化的对象,将p3的控制权转移给p2。
release()使用提示。
release()会切断unique_ptr和它原来管理的对象间的联系。release()返回的指针必须被记录,否则我们将失去它。
p2.release(); // 错误:p2并未释放内存,只是放弃了该内存的控制权,导致我们失去了该指针 auto p = p2.release(); // 正确:但要记得delete p
删除器
向unique_ptr传递删除器。
智能指针在管理动态内存时使用delete来释放资源,当使用智能指针管理非动态内存(如 myclass a)时,我们需要定义删除器函数来代替delete完成对只能指针进行释放操作。
void fuc() { myclass a; unique_ptr<myclass, decltype(end_fuc)*> p(&a, end_fuc); }// fuc退出时,即使程序发生异常 shared_ptr也能通过调用end_fuc管理对象
定义了删除器的智能指针,其在销毁时不会执行delete,而是调用删除器函数。
使用decltype来指明函数指针类型,decltype(end_fuc)返回一个函数类型,所以添加一个*来指明我们使用该类型的一个指针。
#c++##智能指针#