重定向unique_ptr会发生什么?

时间:2016-03-08 00:20:34

标签: c++ c++11 unique-ptr

我理解unique_ptr是某个对象的单个所有者,当该对象超出范围时,它会释放该对象。我不明白的是以下情况:

unique_ptr<int> p(new int(1));
p = unique_ptr<int>(new int(2));

如果new int(1)被重定向到另一个内存位置p,那么第一个对象new int(2)会发生什么?(因为p只能拥有其中一个)?

2 个答案:

答案 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)创建新的整数。
  • 将指向此新int的指针传递给刚刚创建的名为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>