C++ 唯一所有权(std :: unique_ptr)
示例
Astd::unique_ptr是一个类模板,它管理动态存储的对象的生存期。对于不同std::shared_ptr的动态对象由只拥有一个实例的std::unique_ptr在任何时间,
//创建一个由唯一指针拥有的值为20的动态int std::unique_ptr<int> ptr = std::make_unique<int>(20);
(注意:std::unique_ptr自C++11和std::make_uniqueC++14起可用。)
只有变量ptr拥有指向动态分配的的指针int。当拥有一个对象的唯一指针超出范围时,将删除拥有的对象,即,如果对象属于类类型,则调用其析构函数,并释放该对象的内存。
要使用std::unique_ptr和std::make_unique用数组类型,利用自己的专长阵:
//创建一个int值为59的unique_ptr std::unique_ptr<int> ptr = std::make_unique<int>(59); //创建一个由15个整数组成的数组的unique_ptr std::unique_ptr<int[]> ptr = std::make_unique<int[]>(15);
您可以std::unique_ptr像访问原始指针一样访问,因为它会使那些运算符过载。
您可以通过使用std::move将智能指针的内容的所有权转移到另一个指针,这将导致原始智能指针指向nullptr。
//1.std::unique_ptr std::unique_ptr<int> ptr = std::make_unique<int>(); //将值更改为1 *ptr = 1; //2.std::unique_ptr(通过将“ptr”移至“ptr2”,“ptr”不再拥有该对象) std::unique_ptr<int> ptr2 = std::move(ptr); int a = *ptr2; //'a'是1 int b = *ptr; //未定义的行为!'ptr'是'nullptr' //(由于上面的move命令)
传递unique_ptr给函数作为参数:
void foo(std::unique_ptr<int> ptr) { //您的代码在这里 } std::unique_ptr<int> ptr = std::make_unique<int>(59); foo(std::move(ptr))
unique_ptr从函数返回。这是编写工厂函数的首选C++11方法,因为它清楚地传达了返回的所有权语义:调用者拥有结果unique_ptr并对其负责。
std::unique_ptr<int> foo() { std::unique_ptr<int> ptr = std::make_unique<int>(59); return ptr; } std::unique_ptr<int> ptr = foo();
比较一下:
int* foo_cpp03(); int* p = foo_cpp03(); //我拥有p吗?我必须在某个时候删除它吗? //答案还不清楚。
make_unique从C++14开始提供类模板。将其手动添加到C++11代码很容易:
template<typename T, typename... Args> typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type make_unique(Args&&... args) { return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); } //对数组使用make_unique template<typename T> typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T>>::type make_unique(size_t n) { return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]()); }