我理解unique_ptr
是某个对象的单个所有者,当该对象超出范围时,它会释放该对象。我不明白的是以下情况:
unique_ptr<int> p(new int(1));
p = unique_ptr<int>(new int(2));
如果new int(1)
被重定向到另一个内存位置p
,那么第一个对象new int(2)
会发生什么?(因为p
只能拥有其中一个)?
答案 0 :(得分:7)
unique_ptr
被销毁或重新安装时, unique_ptr
会破坏它所拥有的对象。例如:
#include <iostream>
#include <memory>
using namespace std;
struct T {
T(int x) : x(x) {
cout << "T(" << x << ")\n";
}
~T() {
cout << "~T(" << x << ")\n";
}
int x;
};
int main() {
unique_ptr<T> p(new T(1));
p = unique_ptr<T>(new T(2));
}
这将打印:
T(1)
创建第一个对象时。T(2)
创建第二个对象时。~T(1)
的赋值运算符释放时,p
。~T(2)
的析构函数释放时,p
。答案 1 :(得分:1)
unique_ptr
以确保第一个int被正确释放,因此它会在其上调用delete
,从而释放保留的内存。
与此代码有些相同:
int* p = new int(1);
delete p;
p = new int(2);
详细情况如下:
new int(1)
创建新的整数。unique_ptr
的{{1}}实例。这是一个只存储指针的对象。p
创建第二个int。new int(2)
将此指针传递给新的unique_ptr
,这是unique_ptr的临时实例(我们将在一秒钟内看到原因)并将指针存储到第二个int。unique_ptr<int>(new int(2))
。现在,赋值运算符被定义为删除先前拥有的对象(第一个int)并获取所分配的unique_ptr(第二个int)所拥有的对象的所有权。实现如下所示。此时p
拥有第二个int,第一个int被删除,临时不再拥有任何对象(持有p
)。nullptr
超出范围,因为我们从未给它命名或存储对它的引用,因此它的析构函数被调用。但它无论如何只保留unique_ptr
。因此,使用原始指针的更详细的等价物将是这样的:
nullptr
编辑跟踪器:
这是visual studio使用的实现(评论也是int* p = new int(1); //create an int
{
int* tmp = new int(2); //create second int
int* del = p; //we need to delete this (first int)
//take ownership of the temporary (second int)
p = tmp;
tmp=nullptr;
//delete the old object (first int)
delete del;
} //tmp and del go out of scope here, but tmp holds the nullptr and del is deleted
//first int is deleted, p points to the second int here
的一部分):
<memory>