我可能没有正确措辞标题,但在以下示例中更容易解释,然后也许有人可以编辑标题。
请考虑以下代码片段:
#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.