Boost C++ 库

...世界上最受推崇和设计最精良的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

PrevUpHomeNext

类模板 unique_ptr

boost::movelib::unique_ptr

概要

// In header: <boost/move/unique_ptr.hpp>

template<typename T, typename D = default_delete<T> > 
class unique_ptr {
public:
  // types
  typedef see_documentation pointer;     
  typedef see_documentation element_type;
  typedef D                 deleter_type;

  // public member functions
  unique_ptr(const unique_ptr &) = delete;
  unique_ptr & operator=(const unique_ptr &) = delete;
  unique_ptr() noexcept;
  unique_ptr(std::nullptr_t) noexcept;
  template<typename Pointer> explicit unique_ptr(Pointer p ) noexcept;
  template<typename Pointer> 
    unique_ptr(Pointer, see_documentation d1 ) noexcept;
  unique_ptr(std::nullptr_t, see_documentation) noexcept;
  template<typename Pointer> 
    unique_ptr(Pointer, see_documentation d2 ) noexcept;
  unique_ptr(std::nullptr_t, see_documentation) noexcept;
  unique_ptr(unique_ptr &&) noexcept;
  template<typename U, typename E> 
    unique_ptr(BOOST_RV_REF_BEG_IF_CXX11  unique_ptr< U, E > BOOST_RV_REF_END_IF_CXX11 u ) noexcept;
  ~unique_ptr();
  unique_ptr & operator=(unique_ptr &&) noexcept;
  template<typename U, typename E> 
    unique_ptr & operator=(unique_ptr< U, E > &&) noexcept;
  unique_ptr & operator=(std::nullptr_t) noexcept;
  element_type & operator*() const noexcept;
  element_type & operator[](std::size_t) const noexcept;
  pointer operator->() const noexcept;
  pointer get() const noexcept;
  D & get_deleter() noexcept;
  const D & get_deleter() const noexcept;
  explicit operator bool() const noexcept;
  pointer release() noexcept;
  template<typename Pointer> void reset(Pointer) noexcept;
  void reset() noexcept;
  void reset(std::nullptr_t) noexcept;
  void swap(unique_ptr &) noexcept;
};

描述

独占指针是一个对象,它拥有另一个对象,并通过指针管理该对象。

更准确地说,独占指针是一个对象 u,它存储一个指向第二个对象 p 的指针,并且当 u 本身被销毁时(例如,当离开块作用域时)将处置 p。在这种情况下,u 被称为拥有 p。

u 处置 p 的机制被称为 p 的关联删除器,这是一个函数对象,其正确的调用会导致 p 的适当处置(通常是其删除)。

令符号 u.p 表示 u 存储的指针,令 u.d 表示关联的删除器。根据请求,u 可以重置(替换)u.p 和 u.d 为另一个指针和删除器,但必须在完成此类替换之前通过关联的删除器正确处置其拥有的对象。

此外,u 可以根据请求将所有权转移到另一个独占指针 u2。在完成此类转移后,以下后置条件成立

  • u2.p 等于转移前的 u.p,

  • u.p 等于 nullptr,并且

  • 如果转移前的 u.d 维护了状态,则该状态已转移到 u2.d。

与重置的情况一样,u2 必须在所有权转移被视为完成之前,通过转移前的关联删除器正确处置其转移前拥有的对象。

从此子条款中指定的 unique_ptr 模板实例化的类型 U 的每个对象都具有上述严格的独占指针所有权语义。为了部分满足这些语义,每个这样的 U 都是 MoveConstructible 和 MoveAssignable,但不是 CopyConstructible 也不是 CopyAssignable。unique_ptr 的模板参数 T 可以是不完整类型。

unique_ptr 的用途包括为动态分配的内存提供异常安全性,将动态分配的内存的所有权传递给函数,以及从函数返回动态分配的内存。

如果 T 是数组类型(例如 unique_ptr<MyType[]>),则接口略有改变

  • 指向从 T 派生的类型的指针会被构造函数和 reset 拒绝。

  • 不提供观察器 operator*operator->

  • 提供索引观察器 operator[]

模板参数

  1. typename T

    提供存储指针的类型。

  2. typename D = default_delete<T>

    删除器类型

    • 模板参数 D 的默认类型是 default_delete。客户端提供的模板参数 D 应为函数对象类型、函数的左值引用或函数对象类型的左值引用,对于这些类型,给定类型为 D 的值 d 和类型为 unique_ptr<T, D>::pointer 的值 ptr,表达式 d(ptr) 是有效的,并且具有适当处置该指针的效果。

    • 如果删除器的类型 D 不是引用类型,则 D 应满足 Destructible 的要求。

    • 如果类型 remove_reference<D>::type::pointer 存在,则它应满足 NullablePointer 的要求。

unique_ptr 公共类型

  1. typedef see_documentation pointer;

    如果类型 remove_reference<D>::type::pointer 存在,则它应是 remove_reference<D>::type::pointer 的同义词。否则,它应是 T* 的同义词。

  2. typedef see_documentation element_type;

    如果 T 是数组类型,则 element_type 等于 T。否则,如果 T 是 U[] 形式的类型,则 element_type 等于 U。

unique_ptr 公共成员函数

  1. unique_ptr(const unique_ptr &) = delete;
  2. unique_ptr & operator=(const unique_ptr &) = delete;
  3. unique_ptr() noexcept;

    要求:D 应满足 DefaultConstructible 的要求,并且该构造不应抛出异常。

    效果:构造一个 unique_ptr 对象,该对象不拥有任何东西,对存储的指针和存储的删除器进行值初始化。

    后置条件get() == nullptrget_deleter() 返回对存储的删除器的引用。

    备注:如果使用指针类型或引用类型实例化此构造函数作为模板参数 D,则程序是非良构的。

  4. unique_ptr(std::nullptr_t) noexcept;

    效果:与 unique_ptr() (默认构造函数)相同。

  5. template<typename Pointer> 
      explicit unique_ptr(Pointer p  BOOST_MOVE_DOCIGN) noexcept;

    要求:D 应满足 DefaultConstructible 的要求,并且该构造不应抛出异常。

    效果:构造一个 unique_ptr,它拥有 p,用 p 初始化存储的指针,并对存储的删除器进行值初始化。

    后置条件get() == pget_deleter() 返回对存储的删除器的引用。

    备注:如果使用指针类型或引用类型实例化此构造函数作为模板参数 D,则程序是非良构的。除非满足以下条件,否则此构造函数不应参与重载解析

    • 如果 T 不是数组类型,并且 Pointer 可以隐式转换为 pointer。

    • 如果 T 是数组类型,并且 Pointer 是指向 element_type 的更 CV 限定的指针。

  6. template<typename Pointer> 
      unique_ptr(Pointer p, see_documentation d1  BOOST_MOVE_DOCIGN) noexcept;

    此构造函数的签名取决于 D 是否为引用类型。

    • 如果 D 是非引用类型 A,则签名是 unique_ptr(pointer p, const A& d)

    • 如果 D 是左值引用类型 A&,则签名是 unique_ptr(pointer p, A& d)

    • 如果 D 是左值引用类型 const A&,则签名是 unique_ptr(pointer p, const A& d)

    要求:满足以下条件之一

    • D 不是左值引用类型,并且 d 是左值或常量右值。D 应满足 CopyConstructible 的要求,并且 D 的复制构造函数不应抛出异常。此 unique_ptr 将保存 d 的副本。

    • D 是左值引用类型,并且 d 是左值。D 引用的类型不需要是 CopyConstructible 或 MoveConstructible。此 unique_ptr 将保存引用左值 d 的 D。

    效果:构造一个 unique_ptr 对象,该对象拥有 p,用 p 初始化存储的指针,并如上所述初始化删除器。

    后置条件get() == pget_deleter() 返回对存储的删除器的引用。如果 D 是引用类型,则 get_deleter() 返回对左值 d 的引用。

    备注:除非满足以下条件,否则此构造函数不应参与重载解析

    • 如果 T 不是数组类型,并且 Pointer 可以隐式转换为 pointer。

    • 如果 T 是数组类型,并且 Pointer 是指向 element_type 的更 CV 限定的指针。

  7. unique_ptr(std::nullptr_t, see_documentation d1) noexcept;

    效果:与 template<class Pointer> unique_ptr(Pointer p, deleter_arg_type1 d1) 相同的效果,并且额外地 get() == nullptr

  8. template<typename Pointer> 
      unique_ptr(Pointer p, see_documentation d2  BOOST_MOVE_DOCIGN) noexcept;

    此构造函数的签名取决于 D 是否为引用类型。

    • 如果 D 是非引用类型 A,则签名是 unique_ptr(pointer p, A&& d)

    • 如果 D 是左值引用类型 A&,则签名是 unique_ptr(pointer p, A&& d)

    • 如果 D 是左值引用类型 const A&,则签名是 unique_ptr(pointer p, const A&& d)

    要求:满足以下条件之一

    • D 不是左值引用类型,并且 d 是非 const 右值。D 应满足 MoveConstructible 的要求,并且 D 的移动构造函数不应抛出异常。此 unique_ptr 将保存从 d 移动构造的值。

    • D 是左值引用类型,并且 d 是右值,则程序是非良构的。

    效果:构造一个 unique_ptr 对象,该对象拥有 p,用 p 初始化存储的指针,并如上所述初始化删除器。

    后置条件get() == pget_deleter() 返回对存储的删除器的引用。如果 D 是引用类型,则 get_deleter() 返回对左值 d 的引用。

    备注:除非满足以下条件,否则此构造函数不应参与重载解析

    • 如果 T 不是数组类型,并且 Pointer 可以隐式转换为 pointer。

    • 如果 T 是数组类型,并且 Pointer 是指向 element_type 的更 CV 限定的指针。

  9. unique_ptr(std::nullptr_t, see_documentation d2) noexcept;

    效果:与 template<class Pointer> unique_ptr(Pointer p, deleter_arg_type2 d2) 相同的效果,并且额外地 get() == nullptr

  10. unique_ptr(unique_ptr && u) noexcept;

    要求:如果 D 不是引用类型,则 D 应满足 MoveConstructible 的要求。从类型 D 的右值构造删除器不应抛出异常。

    效果:通过将所有权从 u 转移到 *this 来构造 unique_ptr。如果 D 是引用类型,则此删除器是从 u 的删除器复制构造的;否则,此删除器是从 u 的删除器移动构造的。

    后置条件get() 产生构造前 u.get() 产生的值。get_deleter() 返回对从 u.get_deleter() 构造的存储的删除器的引用。如果 D 是引用类型,则 get_deleter()u.get_deleter() 都引用相同的左值删除器。

  11. template<typename U, typename E> 
      unique_ptr(BOOST_RV_REF_BEG_IF_CXX11  unique_ptr< U, E > BOOST_RV_REF_END_IF_CXX11 u  BOOST_MOVE_DOCIGN) noexcept;

    要求:如果 E 不是引用类型,则从类型 E 的右值构造删除器应该是良构的,并且不应抛出异常。否则,E 是引用类型,并且从类型 E 的左值构造删除器应该是良构的,并且不应抛出异常。

    备注:除非满足以下条件,否则此构造函数不应参与重载解析

    • unique_ptr<U, E>::pointer 可以隐式转换为 pointer,

    • U 不是数组类型,并且

    • D 是引用类型且 E 与 D 的类型相同,或者 D 不是引用类型且 E 可以隐式转换为 D。

    效果:通过将所有权从 u 转移到 *this 来构造 unique_ptr。如果 E 是引用类型,则此删除器是从 u 的删除器复制构造的;否则,此删除器是从 u 的删除器移动构造的。

    后置条件get() 产生构造前 u.get() 产生的值。get_deleter() 返回对从 u.get_deleter() 构造的存储的删除器的引用。

  12. ~unique_ptr();

    要求:表达式 get_deleter()(get()) 应该是良构的,应该具有明确定义的行为,并且不应抛出异常。

    效果:如果 get() == nullpt1r 则没有效果。否则 get_deleter()(get())

    注意default_delete 的使用要求 T 是完整类型

  13. unique_ptr & operator=(unique_ptr && u) noexcept;

    要求:如果 D 不是引用类型,则 D 应满足 MoveAssignable 的要求,并且从类型 D 的右值赋值删除器不应抛出异常。否则,D 是引用类型;remove_reference<D>::type 应满足 CopyAssignable 的要求,并且从类型 D 的左值赋值删除器不应抛出异常。

    效果:将所有权从 u 转移到 *this,就像调用 reset(u.release()) 后跟 get_deleter() = std::forward<D>(u.get_deleter()) 一样。

    返回:*this。

  14. template<typename U, typename E> 
      unique_ptr & operator=(unique_ptr< U, E > && u) noexcept;

    要求:如果 E 不是引用类型,则从类型 E 的右值赋值删除器应该是良构的,并且不应抛出异常。否则,E 是引用类型,并且从类型 E 的左值赋值删除器应该是良构的,并且不应抛出异常。

    备注:除非满足以下条件,否则此运算符不应参与重载解析

    效果:将所有权从 u 转移到 *this,就像调用 reset(u.release()) 后跟 get_deleter() = std::forward<E>(u.get_deleter()) 一样。

    返回:*this。

  15. unique_ptr & operator=(std::nullptr_t) noexcept;

    效果reset()

    后置条件get() == nullptr

    返回:*this。

  16. element_type & operator*() const noexcept;

    要求get() != nullptr

    返回*get()

    备注</b: 如果 T 是数组类型,则程序是非良构的。

  17. element_type & operator[](std::size_t i) const noexcept;

    要求:i < 存储指针指向的数组中的元素数量。

    返回get()[i]

    备注</b: 如果 T 不是数组类型,则程序是非良构的。

  18. pointer operator->() const noexcept;

    要求get() != nullptr

    返回get()

    注意:通常使用要求 T 是完整类型。

    备注</b: 如果 T 是数组类型,则程序是非良构的。

  19. pointer get() const noexcept;

    返回:存储的指针。

  20. D & get_deleter() noexcept;

    返回:对存储的删除器的引用。

  21. const D & get_deleter() const noexcept;

    返回:对存储的删除器的引用。

  22. explicit operator bool() const noexcept;

    返回:返回:get() != nullptr。

  23. pointer release() noexcept;

    后置条件get() == nullptr

    返回:值 get() 在调用 release 开始时具有的值。

  24. template<typename Pointer> void reset(Pointer p) noexcept;

    要求:表达式 get_deleter()(get()) 应该是良构的,应该具有明确定义的行为,并且不应抛出异常。

    效果:将 p 赋值给存储的指针,然后,如果存储的指针的旧值 old_p 不等于 nullptr,则调用 get_deleter()(old_p)。注意:这些操作的顺序很重要,因为调用 get_deleter() 可能会销毁 *this。

    后置条件get() == p。注意:如果调用 get_deleter() 销毁了 *this,则后置条件不成立,因为 this->get() 不再是有效的表达式。

    备注:除非满足以下条件,否则此构造函数不应参与重载解析

    • 如果 T 不是数组类型,并且 Pointer 可以隐式转换为 pointer。

    • 如果 T 是数组类型,并且 Pointer 是指向 element_type 的更 CV 限定的指针。

  25. void reset() noexcept;

    要求:表达式 get_deleter()(get()) 应该是良构的,应该具有明确定义的行为,并且不应抛出异常。

    效果:将 nullptr 赋值给存储的指针,然后,如果存储的指针的旧值 old_p 不等于 nullptr,则调用 get_deleter()(old_p)。注意:这些操作的顺序很重要,因为调用 get_deleter() 可能会销毁 *this。

    后置条件get() == p。注意:如果调用 get_deleter() 销毁了 *this,则后置条件不成立,因为 this->get() 不再是有效的表达式。

  26. void reset(std::nullptr_t) noexcept;

    效果:与 reset() 相同

  27. void swap(unique_ptr & u) noexcept;

    要求get_deleter() 应该是可交换的,并且在交换下不应抛出异常。

    效果:对 *this 和 u 的存储指针和存储删除器调用 swap。


PrevUpHomeNext