接口文档可参见std::unique_ptr
在C++中,动态内存的管理是通过一对运算符来完成的:new,在动态内存中为对象分配空间并返回一个指向该对象的指针,可以选择对对象进行初始化;delete,接受一个动态对象的指针,销毁该对象,并释放与之关联的内存。但是动态内存的使用很容易出问题,因为确保在正确的时间释放内存是极其困难的。
为了更容易同时也更安全地使用动态内存,C++11标准库提供了两种智能指针(smart pointer)类型来管理动态对象。智能指针的行为类似常规指针,重要的区别是它负责自动释放所指的对象。
C++11标准库提供的这两种智能指针的区别在于管理底层指针的方式:shared_ptr允许多个指针指向同一个对象;unique_ptr则"独占"所指向的对象。C++11标准库还定义了一个名为weak_ptr的辅助类,它是一种弱引用,指向shared_ptr所管理的对象。这三种类型都定义在memory头文件中。
智能指针是模板类而不是指针。当创建一个智能指针时,必须提供额外的信息即指针可以指向的类型。默认初始化的智能指针中保存着一个空指针。
unique_ptr是C++11标准中用来取代std::auto_ptr的指针容器(在C++11中,auto_ptr被废弃)。它不能与其它unique_ptr类型的指针对象共享所指对象的内存。这种”所有权”仅能够通过标准库的move函数来转移。unique_ptr是一个删除了拷贝构造函数、保留了移动构造函数的指针封装类型。
获得内部对象的指针, 由于已经重载了方法, 因此和直接使用对象是一样的.如 unique_ptr sp(new int(1)); sp 与 sp.get()是等价的
放弃内部对象的所有权,将内部指针置为空, release 返回的指针通常被用来初始化另一个智能指针或给另一个智能指针赋值。如果不用另一个智能指针来保存release返回的指针,程序就要负责资源的释放。
reset 销毁内部对象并接受新的对象的所有权(如果使用缺省参数的话,也就是没有任何对象的所有权, 此时仅将内部对象释放, 并置为空)
swap 交换两个unique_ptr所管理的对象。
详见下代码
使用如下:
#include <iostream> #include <memory> int main() { int *num = new int(10); std::cout << "num address: " << num << std::endl; std::unique_ptr<int> uptr(num); //绑定动态对象 //std::unique_ptr<int> uptr2 = uptr; //不能賦值 //std::unique_ptr<int> uptr2(uptr); //不能拷内 std::cout<<"*uptr = "<< *uptr << std::endl; std::cout<<"uptr.get() = "<< uptr.get() << std::endl; std::unique_ptr<int> uptr2 = std::move(uptr); //替换所有权 if(uptr == nullptr) std::cout<<"uptr give up *int"<<std::endl; std::cout<<"*uptr2 = "<< *uptr2 << std::endl; int *p = uptr2.release(); //uptr2释放对指针的控制权,返回指针,并将uptr2置为空 if(uptr2 == nullptr) std::cout<<"uptr2 give up *int"<<std::endl; std::cout<<"*p = "<< *p << std::endl; delete p; // 手动释放 std::unique_ptr<int> uptr3(new int(100)); //绑定动态对象 std::cout<<"*uptr3 = "<< *uptr3 << std::endl; uptr3.reset(new int(90)); // 销毁内部对象并接受新的对象的所有权 std::cout<<"*uptr3 = "<< *uptr3 << std::endl; std::unique_ptr<int> uptr4(new int(110)); //绑定动态对象 std::cout<<"*uptr4 = "<< *uptr4 << std::endl; uptr4.swap(uptr3); //交换两个unique_ptr所管理的对象 std::cout<<"*uptr3 = "<< *uptr3 << std::endl; std::cout<<"*uptr4 = "<< *uptr4 << std::endl; std::unique_ptr<int []> ups(new int[10]); for (int i = 0; i < 10; i++) { ups[i] = i; } for (int j = 0; j < 10; ++j) { std::cout<<"ups["<< j << "] = "<< ups[j]<<std::endl; } return 0; }输出:
num address: 0x55a1fdeade70 *uptr = 10 uptr.get() = 0x55a1fdeade70 uptr give up *int *uptr2 = 10 uptr2 give up *int *p = 10 *uptr3 = 100 *uptr3 = 90 *uptr4 = 110 *uptr3 = 110 *uptr4 = 90 ups[0] = 0 ups[1] = 1 ups[2] = 2 ups[3] = 3 ups[4] = 4 ups[5] = 5 ups[6] = 6 ups[7] = 7 ups[8] = 8 ups[9] = 9