std :: unique_ptr是RAII的应用吗?

时间:2015-03-31 15:53:45

标签: c++ unique-ptr

这是对它的准确描述吗?它有意义吗?

您是否确保在unique_ptr超出范围之前删除它指向的对象[即使您没有使用unique_ptr]?

4 个答案:

答案 0 :(得分:11)

是的,std::unique_ptr遵循RAII设计原则。

不,std::unique_ptr不会阻止其他代码执行愚蠢的操作,例如在属于delete的指针上调用unique_ptrunique_ptr本身将在它拥有的对象上调用删除器 1

  1. 它超出了范围
    1. 重新分配unique_ptr(通过operator=reset)以指向其他对象
    2. 还可以通过移动到其他智能指针或使用unique_ptr成员函数来撤消release对象的所有权。这会破坏对象与unique_ptr之间的关联,而unique_ptr将不再清理对象。


      1 默认删除器将使用deletedelete [],具体取决于目标是否具有数组类型。但unique_ptr是一个模板,可以自定义其删除工具,例如FILE*的清理操作可以选择为fclose的调用。

      此功能可用于在unique_ptr超出范围时安排任意清除操作。 RAII用于保持锁定,关闭文件等等 - 显然,如果早期执行清理操作只会因为编译器未看到智能指针的任何未来使用而存在重大问题。幸运的是,C ++对象的生命周期规则是完全确定的(甚至在同一范围内的多个自动变量的破坏顺序也很明确),并且当智能指针本身被破坏时,您可以依靠智能指针清理其拥有的对象。

答案 1 :(得分:2)

std::unique_ptr是RAII,因为对象的创建也会初始化它。

  

您是否保证在unique_ptr超出范围之前不会删除它指向的对象[即使您没有使用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
}