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



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

请考虑以下代码片段:

#include <iostream>
#include <memory> // for std::unique_ptr
class Resource
{
public:
Resource() { std::cout << "Resource acquiredn"; }
~Resource() { std::cout << "Resource destroyedn"; }
};
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 nulln" : "nulln");
return 0;
}

这将打印:

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

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

但是,假设我们仍然手动删除资源(之后不将其设置为 null),如上面的代码所示。那么,当 res1 超出范围时,它不会尝试删除已经解除分配的内容吗?

是的,在这种情况下,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.

相关内容

  • 没有找到相关文章

最新更新