如何声明std::unique_ptr以及它的用途
How to declare std::unique_ptr and what is the use of it?
我试图了解std::unique_ptr
是如何工作的,为此我找到了这个文档。作者从下面的例子开始:
#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));
我们使用integer作为实参(在圆括号之间),这里
unique_ptr<double> uptr2 (pd);
使用指针作为实参。这有什么区别吗?
我也不清楚的是,以这种方式声明的指针与"正常"声明的指针有何不同。div。
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
是不可复制的。
只要你使用智能指针的方式不违反它们要求你遵守的隐式契约,你就可以保证内存不会泄露,并且对象的适当所有权策略将被强制执行。
对unique_ptr进行赋值操作的两个概念没有区别。
int* intPtr = new int(3);
unique_ptr<int> uptr (intPtr);
类似于
unique_ptr<int> uptr (new int(3));
这里unique_ptr自动删除uptr
占用的空间。
以这种方式声明的指针与以"普通"方式声明的指针有何不同?方式。
如果在堆空间中创建一个整数(使用new关键字或malloc),则必须自己清除该内存(分别使用delete或free)。
在下面的代码中,
int* heapInt = new int(5);//initialize int in heap memory
.
.//use heapInt
.
delete heapInt;
在这里,当使用完成后,您必须删除 heapInt。如果不删除,则会发生内存泄漏。
为了避免这种内存泄漏,使用了unique_ptr,当heapInt超出作用域时,unique_ptr会自动删除它所占用的空间。因此,您不需要为unique_ptr执行delete或free
唯一指针保证在超出作用域时销毁其管理的对象。http://en.cppreference.com/w/cpp/memory/unique_ptr
在本例中:
unique_ptr<double> uptr2 (pd);
当uptr2
超出作用域时, pd
将被销毁。通过自动删除,方便了内存管理。
unique_ptr<int> uptr (new int(3));
的情况没有什么不同,只是原始指针在这里没有分配给任何变量。
从cppreference中,有一个std::unique_ptr
构造函数是
因此,创建一个新的std::unique_ptr
就是传递一个指针给它的构造函数。
unique_ptr<int> uptr (new int(3));
或者与
相同int *int_ptr = new int(3);
std::unique_ptr<int> uptr (int_ptr);
不同的是你不用在使用后清理。如果你不使用std::unique_ptr
(智能指针),你将不得不像这样删除它
delete int_ptr;
,当您不再需要它或它将导致内存泄漏。
- 为什么 std::unique 不调用 std::sort?
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 生成"unique"矩阵
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 我对 std::unique(算法)C++有问题
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- std::shared_ptr::unique(),复制和线程安全
- 如何在C++03中用自定义谓词调用std::unique
- C++中的指针否定 (!ptr == NULL)
- C++14 unique_ptr并使用已删除的函数'std::unique-ptr' unique_ptr错误