手动删除拥有的对象后,std :: unique_ptr超出范围时如何工作?

时间:2019-06-21 20:52:22

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

我可能没有正确写出标题,但在下面的示例中更容易解释,然后也许有人可以编辑标题。

请考虑以下代码段:

#include <iostream>
#include <memory> // for std::unique_ptr

class Resource
{
public:
    Resource() { std::cout << "Resource acquired\n"; }
    ~Resource() { std::cout << "Resource destroyed\n"; }
};

int main()
{
    Resource* res = new Resource;
    std::unique_ptr<Resource> res1(res); // Resource created here
    delete res;

    std::cout << "res1 is " << (static_cast<bool>(res1) ? "not null\n" : "null\n");

    return 0;
}

此打印:

$ ./a.out 
Resource acquired
Resource destroyed
res1 is not null
Resource destroyed

我们创建了一个动态分配的资源,然后创建了拥有该资源的唯一指针(res1)。唯一的指针使我们不必担心必须手动删除资源。

但是,让我们假设像上面的代码一样,无论如何都要手动删除资源(此后不将其设置为null)。然后,当res1超出范围时,难道不是要删除已经被释放的东西吗?

1 个答案:

答案 0 :(得分:5)

是的,在这种情况下,unique_ptr将在对象超出范围后尝试删除该对象。实际上,上面显示的示例是说明unique_ptr的关键属性之一的完美方法:如果您拥有由unique_ptr管理的资源,则不应尝试自己管理该资源在unique_ptr之外。毕竟,与unique_ptr的合同是“ unique_ptr专有地拥有该资源”,因此,如果您获取该资源并自己进行分配,则会违反合同。

换句话说,unique_ptr所做的工作比“使我们不必担心必须手动删除资源”要强一些。相反,它承担管理资源的全部和排他性责任。

例如,shared_ptr可能会出现类似的问题,它假定资源的所有所有权在资源的不同shared_ptr之间共享。

如果要在函数返回之前显式释放资源,请使用reset函数:

res1.reset(); // Cleans up the resource.