如何声明std :: unique_ptr以及它的用途是什么?

问题描述 投票:67回答:3

我试着理解std::unique_ptr是如何工作的,为此我找到了this文件。作者从以下示例开始:

#include <utility>  //declarations of unique_ptr
using std::unique_ptr;
// default construction
unique_ptr<int> up; //creates an empty object
// initialize with an argument
unique_ptr<int> uptr (new int(3));
double *pd= new double;
unique_ptr<double> uptr2 (pd);
// overloaded * and ->
*uptr2 = 23.5;
unique_ptr<std::string> ups (new std::string("hello"));
int len=ups->size();

令我困惑的是,在这一行

unique_ptr<int> uptr (new int(3));

我们使用整数作为参数(在圆括号之间)和这里

unique_ptr<double> uptr2 (pd);

我们使用指针作为参数。它有什么不同吗?

对我来说还不清楚的是,以这种方式声明的指针将如何与以“正常”方式声明的指针不同。

c++ pointers std unique-ptr
3个回答
66
投票

unique_ptr<T>的构造函数接受一个指向T类型的对象的原始指针(因此,它接受一个T*)。

在第一个例子中:

unique_ptr<int> uptr (new int(3));

指针是new表达式的结果,而在第二个示例中:

unique_ptr<double> uptr2 (pd);

指针存储在pd变量中。

从概念上讲,没有任何改变(你正在从原始指针构造一个unique_ptr),但第二种方法可能更危险,因为它允许你,例如,做:

unique_ptr<double> uptr2 (pd);
// ...
unique_ptr<double> uptr3 (pd);

因此,有两个唯一的指针有效地封装了同一个对象(因此违反了唯一指针的语义)。

这就是为什么在可能的情况下创建唯一指针的第一种形式更好。请注意,在C ++ 14中我们将能够:

unique_ptr<int> p = make_unique<int>(42);

哪个更清晰,更安全。现在关于你的怀疑:

对我来说还不清楚的是,以这种方式声明的指针将如何与以“正常”方式声明的指针不同。

智能指针应该模拟对象所有权,并且当指向该对象的最后一个(智能,拥有)指针超出范围时,自动处理销毁指向对象。

这样你就不必记住在动态分配的对象上做delete - 智能指针的析构函数会为你做这个 - 也不用担心你是否不会取消引用已经被破坏的对象的(悬空)指针:

{
    unique_ptr<int> p = make_unique<int>(42);
    // Going out of scope...
}
// I did not leak my integer here! The destructor of unique_ptr called delete

现在unique_ptr是一个模拟独特所有权的智能指针,这意味着在你的程序中任何时候只有一个(拥有)指向指向对象的指针 - 这就是为什么unique_ptr是不可复制的。

只要您使用智能指针的方式不会违反它们要求您遵守的隐式契约,您就可以保证不会泄漏任何内存,并且将强制执行对象的正确所有权策略。原始指针不会给你这个保证。


8
投票

赋值给unique_ptr的两个概念都没有区别。

int* intPtr = new int(3);
unique_ptr<int> uptr (intPtr);

类似于

unique_ptr<int> uptr (new int(3));

这里unique_ptr会自动删除uptr占用的空间。

如何以这种方式声明的指针将与以“正常”方式声明的指针不同。

如果在堆空间中创建一个整数(使用new keyword或malloc),则必须自己清除该内存(分别使用delete或free)。

在下面的代码中,

int* heapInt = new int(5);//initialize int in heap memory
.
.//use heapInt
.
delete heapInt;

在这里,你必须删除heapInt,完成后使用。如果未删除,则会发生内存泄漏。

为了避免这种内存泄漏,使用unique_ptr,其中unique_ptr会在超出范围时自动删除heapInt占用的空间。


6
投票

保证唯一指针在超出范围时销毁它们管理的对象。 http://en.cppreference.com/w/cpp/memory/unique_ptr

在这种情况下:

unique_ptr<double> uptr2 (pd);

pd超出范围时,uptr2将被销毁。这通过自动删除来促进存储器管理。

unique_ptr<int> uptr (new int(3));的情况没有什么不同,除了原始指针没有分配给任何变量。

© www.soinside.com 2019 - 2024. All rights reserved.