编程语言
首页 > 编程语言> > c++智能指针解析

c++智能指针解析

作者:互联网

1.auto_ptr 概述:C++98中引入auto_ptr,但是实现有缺陷(使用copy语义转移资源),现已弃用,在实际项目中不应该使用。
点击查看代码 ``` // CLASS TEMPLATE auto_ptr template class auto_ptr { // wrap an object pointer to ensure destruction public: typedef _Ty element_type; explicit auto_ptr(_Ty * _Ptr = nullptr) noexcept : _Myptr(_Ptr) { // construct from object pointer } auto_ptr(auto_ptr& _Right) noexcept : _Myptr(_Right.release()) { // construct by assuming pointer from _Right auto_ptr } auto_ptr(auto_ptr_ref<_Ty> _Right) noexcept { // construct by assuming pointer from _Right auto_ptr_ref _Ty * _Ptr = _Right._Ref; _Right._Ref = nullptr; // release old _Myptr = _Ptr; // reset this } template operator auto_ptr<_Other>() noexcept { // convert to compatible auto_ptr return (auto_ptr<_Other>(*this)); } template operator auto_ptr_ref<_Other>() noexcept { // convert to compatible auto_ptr_ref _Other * _Cvtptr = _Myptr; // test implicit conversion auto_ptr_ref<_Other> _Ans(_Cvtptr); _Myptr = nullptr; // pass ownership to auto_ptr_ref return (_Ans); } template auto_ptr& operator=(auto_ptr<_Other>& _Right) noexcept { // assign compatible _Right (assume pointer) reset(_Right.release()); return (*this); } template auto_ptr(auto_ptr<_Other>& _Right) noexcept : _Myptr(_Right.release()) { // construct by assuming pointer from _Right } auto_ptr& operator=(auto_ptr& _Right) noexcept { // assign compatible _Right (assume pointer) reset(_Right.release()); return (*this); } auto_ptr& operator=(auto_ptr_ref<_Ty> _Right) noexcept { // assign compatible _Right._Ref (assume pointer) _Ty * _Ptr = _Right._Ref; _Right._Ref = 0; // release old reset(_Ptr); // set new return (*this); } ~auto_ptr() noexcept { // destroy the object delete _Myptr; } _NODISCARD _Ty& operator*() const noexcept { // return designated value #if _ITERATOR_DEBUG_LEVEL == 2 _STL_VERIFY(_Myptr, "auto_ptr not dereferencable"); #endif /* _ITERATOR_DEBUG_LEVEL == 2 */ return (*get()); } _NODISCARD _Ty * operator->() const noexcept { // return pointer to class object #if _ITERATOR_DEBUG_LEVEL == 2 _STL_VERIFY(_Myptr, "auto_ptr not dereferencable"); #endif /* _ITERATOR_DEBUG_LEVEL == 2 */ return (get()); } _NODISCARD _Ty * get() const noexcept { // return wrapped pointer return (_Myptr); } _Ty * release() noexcept { // return wrapped pointer and give up ownership _Ty * _Tmp = _Myptr; _Myptr = nullptr; return (_Tmp); } void reset(_Ty * _Ptr = nullptr) { // destroy designated object and store new pointer if (_Ptr != _Myptr) delete _Myptr; _Myptr = _Ptr; } private: _Ty * _Myptr; // the wrapped object pointer }; template<> class auto_ptr { public: typedef void element_type; }; #endif /* _HAS_AUTO_PTR_ETC */ ```
2.unique_ptr 概述: unique_ptr 不共享其指针。 它不能复制到另一个 ,按值传递给函数,也不能在需要创建副本的任何 C++ 标准库算法 unique_ptr 中使用。 只能移动 unique_ptr。 这意味着,内存资源所有权将转移到另一 unique_ptr,并且原始 unique_ptr 不再拥有此资源。 我们建议你将对象限制为由一个所有者所有,因为多个所有权会使程序逻辑变得复杂。 因此,当需要纯 C++ 对象的智能指针时,请使用 ,在构造 时,请使用 make_unique unique_ptrunique_ptr 程序函数。 unique_ptr 下图演示了两个 unique_ptr 实例之间的所有权转换。 ![](https://www.icode9.com/i/l/?n=20&i=blog/1367831/202112/1367831-20211220181743352-1938754994.png) 显示移动唯一指针所有权的关系图。 unique_ptr 在 C++ 标准库的 标头中定义。 它的效率与原始指针完全相同,可用于 C++ 标准库容器。 向 C++ 标准库容器添加 实例非常高效,因为 的移动构造函数无需 unique_ptrunique_ptr 复制操作
点击查看代码 ``` // CLASS TEMPLATE unique_ptr SCALAR template // = default_delete<_Ty> class unique_ptr : public _Unique_ptr_base<_Ty, _Dx> { // non-copyable pointer to an object public: typedef _Unique_ptr_base<_Ty, _Dx> _Mybase; typedef typename _Mybase::pointer pointer; typedef _Ty element_type; typedef _Dx deleter_type; using _Mybase::get_deleter; template = 0> constexpr unique_ptr() noexcept : _Mybase(pointer()) { // default construct } template = 0> constexpr unique_ptr(nullptr_t) noexcept : _Mybase(pointer()) { // null pointer construct } unique_ptr& operator=(nullptr_t) noexcept { // assign a null pointer reset(); return (*this); } template = 0> explicit unique_ptr(pointer _Ptr) noexcept : _Mybase(_Ptr) { // construct with pointer } template, int> = 0> unique_ptr(pointer _Ptr, const _Dx& _Dt) noexcept : _Mybase(_Ptr, _Dt) { // construct with pointer and (maybe const) deleter& } template>, is_constructible<_Dx2, _Dx2>>, int> = 0> unique_ptr(pointer _Ptr, _Dx&& _Dt) noexcept : _Mybase(_Ptr, _STD move(_Dt)) { // construct by moving deleter } template, is_constructible<_Dx2, remove_reference_t<_Dx2>>>, int> = 0> unique_ptr(pointer, remove_reference_t<_Dx>&&) = delete; unique_ptr(unique_ptr&& _Right) noexcept : _Mybase(_Right.release(), _STD forward<_Dx>(_Right.get_deleter())) { // construct by moving _Right } template>, is_convertible::pointer, pointer>, conditional_t<is_reference_v<_dx>, is_same<_Dx2, _Dx>, is_convertible<_Dx2, _Dx>> >, int> = 0> unique_ptr(unique_ptr<_Ty2, _Dx2>&& _Right) noexcept : _Mybase(_Right.release(), _STD forward<_Dx2>(_Right.get_deleter())) { // construct by moving _Right } #if _HAS_AUTO_PTR_ETC template, is_same<_Dx, default_delete<_Ty>>>, int> = 0> unique_ptr(auto_ptr<_Ty2>&& _Right) noexcept : _Mybase(_Right.release()) { // construct by moving _Right } #endif /* _HAS_AUTO_PTR_ETC */ template>, is_assignable<_Dx&, _Dx2>, is_convertible::pointer, pointer> >, int> = 0> unique_ptr& operator=(unique_ptr<_Ty2, _Dx2>&& _Right) noexcept { // assign by moving _Right reset(_Right.release()); this->get_deleter() = _STD forward<_Dx2>(_Right.get_deleter()); return (*this); } unique_ptr& operator=(unique_ptr&& _Right) noexcept { // assign by moving _Right if (this != _STD addressof(_Right)) { // different, do the move reset(_Right.release()); this->get_deleter() = _STD forward<_Dx>(_Right.get_deleter()); } return (*this); } void swap(unique_ptr& _Right) noexcept { // swap elements _Swap_adl(this->_Myptr(), _Right._Myptr()); _Swap_adl(this->get_deleter(), _Right.get_deleter()); } ~unique_ptr() noexcept { // destroy the object if (get() != pointer()) { this->get_deleter()(get()); } } _NODISCARD add_lvalue_reference_t<_Ty> operator*() const { // return reference to object return (*get()); } _NODISCARD pointer operator->() const noexcept { // return pointer to class object return (this->_Myptr()); } _NODISCARD pointer get() const noexcept { // return pointer to object return (this->_Myptr()); } explicit operator bool() const noexcept { // test for non-null pointer return (get() != pointer()); } pointer release() noexcept { // yield ownership of pointer pointer _Ans = get(); this->_Myptr() = pointer(); return (_Ans); } void reset(pointer _Ptr = pointer()) noexcept { // establish new pointer pointer _Old = get(); this->_Myptr() = _Ptr; if (_Old != pointer()) { this->get_deleter()(_Old); } } unique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete; }; ```

标签:unique,Right,auto,noexcept,c++,解析,pointer,ptr,指针
来源: https://www.cnblogs.com/shenyantao/p/15712341.html