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

use*_*485 1 c++ smart-pointers unique-ptr c++11

我可能未正确输入标题,但在以下示例中更容易解释,然后有人可以编辑标题。

考虑以下代码片段:

#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;
}
Run Code Online (Sandbox Code Playgroud)

打印:

$ ./a.out 
Resource acquired
Resource destroyed
res1 is not null
Resource destroyed
Run Code Online (Sandbox Code Playgroud)

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

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

tem*_*def 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.
Run Code Online (Sandbox Code Playgroud)

  • 如果两次取消分配相同的资源,则会得到“不确定的行为”,这意味着无法保证会发生什么。它可能发生段错误,或者可能破坏内存管理器的状态并导致下游发生各种可怕的事情,或者可能完全无害。这就是C ++的奇妙世界。:-) (7认同)