这是对它的准确描述吗?它有意义吗?
您是否确保在unique_ptr超出范围之前删除它指向的对象[即使您没有使用unique_ptr]?
答案 0 :(得分:11)
是的,std::unique_ptr
遵循RAII设计原则。
不,std::unique_ptr
不会阻止其他代码执行愚蠢的操作,例如在属于delete
的指针上调用unique_ptr
。 unique_ptr
本身将在它拥有的对象上调用删除器 1 :
或
unique_ptr
(通过operator=
或reset
)以指向其他对象还可以通过移动到其他智能指针或使用unique_ptr
成员函数来撤消release
对象的所有权。这会破坏对象与unique_ptr
之间的关联,而unique_ptr
将不再清理对象。
1 默认删除器将使用delete
或delete []
,具体取决于目标是否具有数组类型。但unique_ptr
是一个模板,可以自定义其删除工具,例如FILE*
的清理操作可以选择为fclose
的调用。
此功能可用于在unique_ptr
超出范围时安排任意清除操作。 RAII用于保持锁定,关闭文件等等 - 显然,如果早期执行清理操作只会因为编译器未看到智能指针的任何未来使用而存在重大问题。幸运的是,C ++对象的生命周期规则是完全确定的(甚至在同一范围内的多个自动变量的破坏顺序也很明确),并且当智能指针本身被破坏时,您可以依靠智能指针清理其拥有的对象。
答案 1 :(得分:2)
std::unique_ptr
是RAII,因为对象的创建也会初始化它。
您是否保证在unique_ptr超出范围之前不会删除它指向的对象[即使您没有使用unique_ptr]?
如果你做了一些假设:
或者说更简洁,是的,它会活得那么久。
答案 2 :(得分:2)
确实是RAII的应用。
但是,在unique_ptr超出范围之前,您不会被授予其指向的对象未被其他人删除。
E.g。
int* p = new int;
int* cp = p;
std::unique_ptr<int> up(p);
delete cp;
会给出未定义的行为。
答案 3 :(得分:1)
std::unique_ptr
可用于RAII,但不会阻止您执行以下操作:
#include <memory>
class Foo{};
int main()
{
Foo* pFoo = new Foo;
std::unique_ptr<Foo> upFoo(pFoo);
delete pFoo; // WRONG, double deletion when upFoo's destructor is called
}
通常,使用智能指针的最佳方法是将原始指针作为构造函数或类似make的函数传递,例如
#include <memory>
class Foo{};
int main()
{
std::unique_ptr<Foo> upFoo(new Foo); // or make_unique in C++14
}