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[]
。
typename T
提供存储指针的类型。
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
公共成员函数unique_ptr(const unique_ptr &) = delete;
unique_ptr & operator=(const unique_ptr &) = delete;
unique_ptr() noexcept;
要求:D 应满足 DefaultConstructible 的要求,并且该构造不应抛出异常。
效果:构造一个 unique_ptr 对象,该对象不拥有任何东西,对存储的指针和存储的删除器进行值初始化。
后置条件:get() == nullptr
。get_deleter()
返回对存储的删除器的引用。
备注:如果使用指针类型或引用类型实例化此构造函数作为模板参数 D,则程序是非良构的。
unique_ptr(std::nullptr_t) noexcept;
效果:与 unique_ptr()
(默认构造函数)相同。
template<typename Pointer> explicit unique_ptr(Pointer p BOOST_MOVE_DOCIGN) noexcept;
要求:D 应满足 DefaultConstructible 的要求,并且该构造不应抛出异常。
效果:构造一个 unique_ptr,它拥有 p,用 p 初始化存储的指针,并对存储的删除器进行值初始化。
后置条件:get() == p
。get_deleter()
返回对存储的删除器的引用。
备注:如果使用指针类型或引用类型实例化此构造函数作为模板参数 D,则程序是非良构的。除非满足以下条件,否则此构造函数不应参与重载解析
如果 T 不是数组类型,并且 Pointer 可以隐式转换为 pointer。
如果 T 是数组类型,并且 Pointer 是指向 element_type 的更 CV 限定的指针。
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() == p
。get_deleter()
返回对存储的删除器的引用。如果 D 是引用类型,则 get_deleter()
返回对左值 d 的引用。
备注:除非满足以下条件,否则此构造函数不应参与重载解析
如果 T 不是数组类型,并且 Pointer 可以隐式转换为 pointer。
如果 T 是数组类型,并且 Pointer 是指向 element_type 的更 CV 限定的指针。
unique_ptr(std::nullptr_t, see_documentation d1) noexcept;
效果:与 template<class Pointer> unique_ptr(Pointer p, deleter_arg_type1 d1)
相同的效果,并且额外地 get() == nullptr
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() == p
。get_deleter()
返回对存储的删除器的引用。如果 D 是引用类型,则 get_deleter()
返回对左值 d 的引用。
备注:除非满足以下条件,否则此构造函数不应参与重载解析
如果 T 不是数组类型,并且 Pointer 可以隐式转换为 pointer。
如果 T 是数组类型,并且 Pointer 是指向 element_type 的更 CV 限定的指针。
unique_ptr(std::nullptr_t, see_documentation d2) noexcept;
效果:与 template<class Pointer> unique_ptr(Pointer p, deleter_arg_type2 d2)
相同的效果,并且额外地 get() == nullptr
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()
都引用相同的左值删除器。
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()
构造的存储的删除器的引用。
~unique_ptr();
要求:表达式 get_deleter()(get())
应该是良构的,应该具有明确定义的行为,并且不应抛出异常。
效果:如果 get() == nullpt1r
则没有效果。否则 get_deleter()(get())
。
注意:default_delete 的使用要求 T 是完整类型
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。
template<typename U, typename E> unique_ptr & operator=(unique_ptr< U, E > && u) noexcept;
要求:如果 E 不是引用类型,则从类型 E 的右值赋值删除器应该是良构的,并且不应抛出异常。否则,E 是引用类型,并且从类型 E 的左值赋值删除器应该是良构的,并且不应抛出异常。
备注:除非满足以下条件,否则此运算符不应参与重载解析
unique_ptr<U, E>::pointer
可以隐式转换为 pointer 并且
U 不是数组类型。
效果:将所有权从 u 转移到 *this,就像调用 reset(u.release())
后跟 get_deleter() = std::forward<E>(u.get_deleter())
一样。
返回:*this。
unique_ptr & operator=(std::nullptr_t) noexcept;
效果:reset()
。
后置条件:get() == nullptr
返回:*this。
element_type & operator*() const noexcept;
要求:get() != nullptr
。
返回:*get()
。
备注</b: 如果 T 是数组类型,则程序是非良构的。
element_type & operator[](std::size_t i) const noexcept;
要求:i < 存储指针指向的数组中的元素数量。
返回:get()[i]
。
备注</b: 如果 T 不是数组类型,则程序是非良构的。
pointer operator->() const noexcept;
要求:get() != nullptr
。
返回:get()
。
注意:通常使用要求 T 是完整类型。
备注</b: 如果 T 是数组类型,则程序是非良构的。
pointer get() const noexcept;
返回:存储的指针。
D & get_deleter() noexcept;
返回:对存储的删除器的引用。
const D & get_deleter() const noexcept;
返回:对存储的删除器的引用。
explicit operator bool() const noexcept;
返回:返回:get() != nullptr。
pointer release() noexcept;
后置条件:get() == nullptr
。
返回:值 get()
在调用 release 开始时具有的值。
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 限定的指针。
void reset() noexcept;
要求:表达式 get_deleter()(get())
应该是良构的,应该具有明确定义的行为,并且不应抛出异常。
效果:将 nullptr 赋值给存储的指针,然后,如果存储的指针的旧值 old_p 不等于 nullptr,则调用 get_deleter()(old_p)
。注意:这些操作的顺序很重要,因为调用 get_deleter()
可能会销毁 *this。
后置条件:get() == p
。注意:如果调用 get_deleter()
销毁了 *this,则后置条件不成立,因为 this->get()
不再是有效的表达式。
void reset(std::nullptr_t) noexcept;
效果:与 reset()
相同
void swap(unique_ptr & u) noexcept;
要求:get_deleter()
应该是可交换的,并且在交换下不应抛出异常。
效果:对 *this 和 u 的存储指针和存储删除器调用 swap。