我可能没有正确写出标题,但在下面的示例中更容易解释,然后也许有人可以编辑标题。
请考虑以下代码段:
#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超出范围时,难道不是要删除已经被释放的东西吗?
答案 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.