`
lobin
  • 浏览: 425824 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论
阅读更多

 

写道
RAII
https://en.cppreference.com/w/cpp/language/raii

 

写道
Object lifetime and resource management (RAII)
https://docs.microsoft.com/en-us/cpp/cpp/object-lifetime-and-resource-management-modern-cpp?view=msvc-170

 

 

智能指针

C++提供了几种智能指针的实现,包括auto_ptr、unique_ptr、shared_ptr、weak_ptr,它们都是一些类模版。其中auto_ptr自C++11开始已经废弃。

 

C++的智能指针为指针(主要是对象资源)提供了一种有限的垃圾回收(garbage collection)功能。相较于其他高级语言的GC支持,C++智能指针提供的这种有限的垃圾回收实在是低级。

 

如下面的示例中,不管是auto_ptr、unique_ptr或者shared_ptr,都不能保证对象资源能够被正确的释放回收。

int *i = new int(100);

std::***_ptr<int> p1(i);

std::***_ptr<int> p2(i); 

 

unique_ptr

unique_ptr定义如下:

template <class T, class D = default_delete<T>>
class unique_ptr
{
public:
    typedef see below pointer;
    typedef T element_type;
    typedef D deleter_type;

    // constructors
    constexpr unique_ptr() noexcept;
    explicit unique_ptr(pointer p) noexcept;
    unique_ptr(pointer p, see below d1) noexcept;
    unique_ptr(pointer p, see below d2) noexcept;
    unique_ptr(unique_ptr&& u) noexcept;
    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
    template <class U, class E>
        unique_ptr(unique_ptr<U, E>&& u) noexcept;
    template <class U>
        unique_ptr(auto_ptr<U>&& u) noexcept;

    // destructor
    ~unique_ptr();

    // assignment
    unique_ptr& operator=(unique_ptr&& u) noexcept;
    template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
    unique_ptr& operator=(nullptr_t) noexcept;

    // observers
    typename add_lvalue_reference<T>::type operator*() const;
    pointer operator->() const noexcept;
    pointer get() const noexcept;
    deleter_type& get_deleter() noexcept;
    const deleter_type& get_deleter() const noexcept;
    explicit operator bool() const noexcept;

    // modifiers
    pointer release() noexcept;
    void reset(pointer p = pointer()) noexcept;
    void swap(unique_ptr& u) noexcept;
};

这里需要注意下几个typedef,element_type、deleter_type这两个还好理解,对应模板参数中的T、D。pointer的定义就不好理解了,除了知道pointer是一个定义的类型之外,“see below”是什么东西?typedef see below pointer;这样的typedef感觉就不是个正经typedef,而且pointer和“see below”还出现了好几次。

 

上面定义中的“see below”让人感觉一头雾水,包括C++标准中很有很多这样的“see below”,可以看下面的定义。

 

pointer

定义如下:

typedef typename __pointer_type<_Tp, deleter_type>::type pointer;

 

pointer的类型定义为__pointer_type<_Tp, deleter_type>中的type类型。

其中__pointer_type定义如下:

template <class _Tp, class _Dp>
struct __pointer_type
{
    typedef typename __pointer_type_imp::__pointer_type<_Tp, typename remove_reference<_Dp>::type>::type type;
};

这里的type类型定义为__pointer_type_imp::__pointer_type<_Tp, typename remove_reference<_Dp>::type>中的type类型。

 

在__pointer_type_imp命名空间中,__pointer_type定义如下:

template <class _Tp, class _Dp, bool = __has_pointer_type<_Dp>::value>
struct __pointer_type
{
    typedef typename _Dp::pointer type;
};

下面是__pointer_type的一个模板特化,__pointer_type_imp::__pointer_type<_Tp, typename remove_reference<_Dp>::type>中的type类型就是下面的特化中的type类型,而这个type的类型其实就是模板参数_Tp的指针类型。

template <class _Tp, class _Dp>
struct __pointer_type<_Tp, _Dp, false>
{
    typedef _Tp* type;
};

根据上面的分析,unique_ptr中的pointer类型其实就是模板参数T的指针类型。即

typedef see below pointer;

等价于

typedef T* pointer;

 

根据下面的定义,

template <class _T1, class _T2>
class __compressed_pair
    : private __libcpp_compressed_pair_imp<_T1, _T2>
{
    typedef __libcpp_compressed_pair_imp<_T1, _T2> base;
public:
    typedef typename base::_T1_param _T1_param;
    typedef typename base::_T2_param _T2_param;

    typedef typename base::_T1_reference _T1_reference;
    typedef typename base::_T2_reference _T2_reference;

    typedef typename base::_T1_const_reference _T1_const_reference;
    typedef typename base::_T2_const_reference _T2_const_reference;

    _LIBCPP_INLINE_VISIBILITY __compressed_pair() {}
    _LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T1_param __t1)
        : base(_VSTD::forward<_T1_param>(__t1)) {}
    _LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T2_param __t2)
        : base(_VSTD::forward<_T2_param>(__t2)) {}
    _LIBCPP_INLINE_VISIBILITY __compressed_pair(_T1_param __t1, _T2_param __t2)
        : base(_VSTD::forward<_T1_param>(__t1), _VSTD::forward<_T2_param>(__t2)) {}

#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)

    _LIBCPP_INLINE_VISIBILITY
    __compressed_pair(const __compressed_pair& __p)
        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&
                   is_nothrow_copy_constructible<_T2>::value)
        : base(__p) {}

    _LIBCPP_INLINE_VISIBILITY
    __compressed_pair& operator=(const __compressed_pair& __p)
        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&
                   is_nothrow_copy_assignable<_T2>::value)
        {
            base::operator=(__p);
            return *this;
        }

    _LIBCPP_INLINE_VISIBILITY
    __compressed_pair(__compressed_pair&& __p)
        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
                   is_nothrow_move_constructible<_T2>::value)
        : base(_VSTD::move(__p)) {}

    _LIBCPP_INLINE_VISIBILITY
    __compressed_pair& operator=(__compressed_pair&& __p)
        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&
                   is_nothrow_move_assignable<_T2>::value)
        {
            base::operator=(_VSTD::move(__p));
            return *this;
        }

#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)

#ifndef _LIBCPP_HAS_NO_VARIADICS

    template <class... _Args1, class... _Args2>
        _LIBCPP_INLINE_VISIBILITY
        __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
                                                      tuple<_Args2...> __second_args)
            : base(__pc, _VSTD::move(__first_args), _VSTD::move(__second_args),
                   typename __make_tuple_indices<sizeof...(_Args1)>::type(),
                   typename __make_tuple_indices<sizeof...(_Args2) >::type())
            {}

#endif  // _LIBCPP_HAS_NO_VARIADICS

    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return base::first();}
    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return base::first();}

    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return base::second();}
    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return base::second();}

    _LIBCPP_INLINE_VISIBILITY void swap(__compressed_pair& __x)
        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
                   __is_nothrow_swappable<_T2>::value)
        {base::swap(__x);}
};

_VSTD在/c++/v1/__config中定义为

#define _VSTD std::_LIBCPP_NAMESPACE

#define _VSTD std::_LIBCPP_NAMESPACE

#define _VSTD std

#define _VSTD std::_LIBCPP_NAMESPACE

 

__compressed_pair继承(private)了__libcpp_compressed_pair_imp

template <class _T1, class _T2, unsigned = __libcpp_compressed_pair_switch<_T1, _T2>::value>
class __libcpp_compressed_pair_imp;

下面是__libcpp_compressed_pair_imp的几个模板特化

0

template <class _T1, class _T2>
class __libcpp_compressed_pair_imp<_T1, _T2, 0>
{
private:
    _T1 __first_;
    _T2 __second_;
public:
    typedef _T1 _T1_param;
    typedef _T2 _T2_param;

    typedef typename remove_reference<_T1>::type& _T1_reference;
    typedef typename remove_reference<_T2>::type& _T2_reference;

    typedef const typename remove_reference<_T1>::type& _T1_const_reference;
    typedef const typename remove_reference<_T2>::type& _T2_const_reference;

    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __first_(), __second_() {}
    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
        : __first_(_VSTD::forward<_T1_param>(__t1)), __second_() {}
    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
        : __first_(), __second_(_VSTD::forward<_T2_param>(__t2)) {}
    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
        : __first_(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}

#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&
                   is_nothrow_copy_constructible<_T2>::value)
        : __first_(__p.first()),
          __second_(__p.second()) {}

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p)
        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&
                   is_nothrow_copy_assignable<_T2>::value)
        {
            __first_ = __p.first();
            __second_ = __p.second();
            return *this;
        }

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
                   is_nothrow_move_constructible<_T2>::value)
        : __first_(_VSTD::forward<_T1>(__p.first())),
          __second_(_VSTD::forward<_T2>(__p.second())) {}

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p)
        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&
                   is_nothrow_move_assignable<_T2>::value)
        {
            __first_ = _VSTD::forward<_T1>(__p.first());
            __second_ = _VSTD::forward<_T2>(__p.second());
            return *this;
        }

#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)

#ifndef _LIBCPP_HAS_NO_VARIADICS

    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
        _LIBCPP_INLINE_VISIBILITY
        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
                                     tuple<_Args1...> __first_args,
                                     tuple<_Args2...> __second_args,
                                     __tuple_indices<_I1...>,
                                     __tuple_indices<_I2...>)
            : __first_(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...),
              __second_(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
            {}

#endif  // _LIBCPP_HAS_NO_VARIADICS

    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return __first_;}
    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return __first_;}

    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return __second_;}
    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return __second_;}

    _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp& __x)
        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
                   __is_nothrow_swappable<_T2>::value)
    {
        using _VSTD::swap;
        swap(__first_, __x.__first_);
        swap(__second_, __x.__second_);
    }
};

1

template <class _T1, class _T2>
class __libcpp_compressed_pair_imp<_T1, _T2, 1>
    : private _T1
{
private:
    _T2 __second_;
public:
    typedef _T1 _T1_param;
    typedef _T2 _T2_param;

    typedef _T1&                                        _T1_reference;
    typedef typename remove_reference<_T2>::type& _T2_reference;

    typedef const _T1&                                        _T1_const_reference;
    typedef const typename remove_reference<_T2>::type& _T2_const_reference;

    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __second_() {}
    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
        : _T1(_VSTD::forward<_T1_param>(__t1)), __second_() {}
    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
        : __second_(_VSTD::forward<_T2_param>(__t2)) {}
    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
        : _T1(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}

#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&
                   is_nothrow_copy_constructible<_T2>::value)
        : _T1(__p.first()), __second_(__p.second()) {}

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p)
        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&
                   is_nothrow_copy_assignable<_T2>::value)
        {
            _T1::operator=(__p.first());
            __second_ = __p.second();
            return *this;
        }

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
                   is_nothrow_move_constructible<_T2>::value)
        : _T1(_VSTD::move(__p.first())), __second_(_VSTD::forward<_T2>(__p.second())) {}

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p)
        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&
                   is_nothrow_move_assignable<_T2>::value)
        {
            _T1::operator=(_VSTD::move(__p.first()));
            __second_ = _VSTD::forward<_T2>(__p.second());
            return *this;
        }

#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)

#ifndef _LIBCPP_HAS_NO_VARIADICS

    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
        _LIBCPP_INLINE_VISIBILITY
        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
                                     tuple<_Args1...> __first_args,
                                     tuple<_Args2...> __second_args,
                                     __tuple_indices<_I1...>,
                                     __tuple_indices<_I2...>)
            : _T1(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...),
              __second_(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
            {}

#endif  // _LIBCPP_HAS_NO_VARIADICS

    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return *this;}
    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return *this;}

    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return __second_;}
    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return __second_;}

    _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp& __x)
        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
                   __is_nothrow_swappable<_T2>::value)
    {
        using _VSTD::swap;
        swap(__second_, __x.__second_);
    }
};

2

template <class _T1, class _T2>
class __libcpp_compressed_pair_imp<_T1, _T2, 2>
    : private _T2
{
private:
    _T1 __first_;
public:
    typedef _T1 _T1_param;
    typedef _T2 _T2_param;

    typedef typename remove_reference<_T1>::type& _T1_reference;
    typedef _T2&                                        _T2_reference;

    typedef const typename remove_reference<_T1>::type& _T1_const_reference;
    typedef const _T2&                                        _T2_const_reference;

    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __first_() {}
    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
        : __first_(_VSTD::forward<_T1_param>(__t1)) {}
    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
        : _T2(_VSTD::forward<_T2_param>(__t2)), __first_() {}
    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
                   is_nothrow_move_constructible<_T2>::value)
        : _T2(_VSTD::forward<_T2_param>(__t2)), __first_(_VSTD::forward<_T1_param>(__t1)) {}

#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&
                   is_nothrow_copy_constructible<_T2>::value)
        : _T2(__p.second()), __first_(__p.first()) {}

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p)
        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&
                   is_nothrow_copy_assignable<_T2>::value)
        {
            _T2::operator=(__p.second());
            __first_ = __p.first();
            return *this;
        }

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
                   is_nothrow_move_constructible<_T2>::value)
        : _T2(_VSTD::forward<_T2>(__p.second())), __first_(_VSTD::move(__p.first())) {}

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p)
        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&
                   is_nothrow_move_assignable<_T2>::value)
        {
            _T2::operator=(_VSTD::forward<_T2>(__p.second()));
            __first_ = _VSTD::move(__p.first());
            return *this;
        }

#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)

#ifndef _LIBCPP_HAS_NO_VARIADICS

    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
        _LIBCPP_INLINE_VISIBILITY
        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
                                     tuple<_Args1...> __first_args,
                                     tuple<_Args2...> __second_args,
                                     __tuple_indices<_I1...>,
                                     __tuple_indices<_I2...>)
            : _T2(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...),
              __first_(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...)
              
            {}

#endif  // _LIBCPP_HAS_NO_VARIADICS

    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return __first_;}
    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return __first_;}

    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return *this;}
    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return *this;}

    _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp& __x)
        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
                   __is_nothrow_swappable<_T2>::value)
    {
        using _VSTD::swap;
        swap(__first_, __x.__first_);
    }
};

  

3

template <class _T1, class _T2>
class __libcpp_compressed_pair_imp<_T1, _T2, 3>
    : private _T1,
      private _T2
{
public:
    typedef _T1 _T1_param;
    typedef _T2 _T2_param;

    typedef _T1& _T1_reference;
    typedef _T2& _T2_reference;

    typedef const _T1& _T1_const_reference;
    typedef const _T2& _T2_const_reference;

    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() {}
    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
        : _T1(_VSTD::forward<_T1_param>(__t1)) {}
    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
        : _T2(_VSTD::forward<_T2_param>(__t2)) {}
    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
        : _T1(_VSTD::forward<_T1_param>(__t1)), _T2(_VSTD::forward<_T2_param>(__t2)) {}

#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&
                   is_nothrow_copy_constructible<_T2>::value)
        : _T1(__p.first()), _T2(__p.second()) {}

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p)
        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&
                   is_nothrow_copy_assignable<_T2>::value)
        {
            _T1::operator=(__p.first());
            _T2::operator=(__p.second());
            return *this;
        }

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
                   is_nothrow_move_constructible<_T2>::value)
        : _T1(_VSTD::move(__p.first())), _T2(_VSTD::move(__p.second())) {}

    _LIBCPP_INLINE_VISIBILITY
    __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p)
        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&
                   is_nothrow_move_assignable<_T2>::value)
        {
            _T1::operator=(_VSTD::move(__p.first()));
            _T2::operator=(_VSTD::move(__p.second()));
            return *this;
        }

#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)

#ifndef _LIBCPP_HAS_NO_VARIADICS

    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
        _LIBCPP_INLINE_VISIBILITY
        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
                                     tuple<_Args1...> __first_args,
                                     tuple<_Args2...> __second_args,
                                     __tuple_indices<_I1...>,
                                     __tuple_indices<_I2...>)
            : _T1(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...),
              _T2(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
            {}

#endif  // _LIBCPP_HAS_NO_VARIADICS

    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return *this;}
    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return *this;}

    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return *this;}
    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return *this;}

    _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp&)
        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
                   __is_nothrow_swappable<_T2>::value)
    {
    }
};

 

 

构造

constexpr unique_ptr() noexcept;

 

    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT
        : __ptr_(pointer())
        {
            static_assert(!is_pointer<deleter_type>::value,
                "unique_ptr constructed with null function pointer deleter");
        }

 

 

explicit unique_ptr(pointer p) noexcept;

    _LIBCPP_INLINE_VISIBILITY explicit unique_ptr(pointer __p) _NOEXCEPT
        : __ptr_(_VSTD::move(__p))
        {
            static_assert(!is_pointer<deleter_type>::value,
                "unique_ptr constructed with null function pointer deleter");
        }

 

 

unique_ptr(pointer p, see below d1) noexcept;

 

unique_ptr(pointer p, see below d2) noexcept;

 

unique_ptr(unique_ptr&& u) noexcept;

 

unique_ptr(nullptr_t) noexcept : unique_ptr() { }

 

还有两个构造函数是函数模板,构造函数是模板的不多见。

 

template <class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept;

 

template <class U> unique_ptr(auto_ptr<U>&& u) noexcept;

 

template <class _Tp, class _Dp = default_delete<_Tp> >
class _LIBCPP_TYPE_VIS_ONLY unique_ptr
{
public:
    typedef _Tp element_type;
    typedef _Dp deleter_type;
    typedef typename __pointer_type<_Tp, deleter_type>::type pointer;
private:
    __compressed_pair<pointer, deleter_type> __ptr_;

#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    unique_ptr(unique_ptr&);
    template <class _Up, class _Ep>
        unique_ptr(unique_ptr<_Up, _Ep>&);
    unique_ptr& operator=(unique_ptr&);
    template <class _Up, class _Ep>
        unique_ptr& operator=(unique_ptr<_Up, _Ep>&);
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES

    struct __nat {int __for_bool_;};

    typedef       typename remove_reference<deleter_type>::type& _Dp_reference;
    typedef const typename remove_reference<deleter_type>::type& _Dp_const_reference;
public:
    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT
        : __ptr_(pointer())
        {
            static_assert(!is_pointer<deleter_type>::value,
                "unique_ptr constructed with null function pointer deleter");
        }
    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT
        : __ptr_(pointer())
        {
            static_assert(!is_pointer<deleter_type>::value,
                "unique_ptr constructed with null function pointer deleter");
        }
    _LIBCPP_INLINE_VISIBILITY explicit unique_ptr(pointer __p) _NOEXCEPT
        : __ptr_(_VSTD::move(__p))
        {
            static_assert(!is_pointer<deleter_type>::value,
                "unique_ptr constructed with null function pointer deleter");
        }

#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    _LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, typename conditional<
                                        is_reference<deleter_type>::value,
                                        deleter_type,
                                        typename add_lvalue_reference<const deleter_type>::type>::type __d)
             _NOEXCEPT
        : __ptr_(__p, __d) {}

    _LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, typename remove_reference<deleter_type>::type&& __d)
             _NOEXCEPT
        : __ptr_(__p, _VSTD::move(__d))
        {
            static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");
        }
    _LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT
        : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {}
    template <class _Up, class _Ep>
        _LIBCPP_INLINE_VISIBILITY
        unique_ptr(unique_ptr<_Up, _Ep>&& __u,
                   typename enable_if
                      <
                        !is_array<_Up>::value &&
                         is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value &&
                         is_convertible<_Ep, deleter_type>::value &&
                         (
                            !is_reference<deleter_type>::value ||
                            is_same<deleter_type, _Ep>::value
                         ),
                         __nat
                      >::type = __nat()) _NOEXCEPT
            : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {}

    template <class _Up>
        _LIBCPP_INLINE_VISIBILITY unique_ptr(auto_ptr<_Up>&& __p,
                typename enable_if<
                                      is_convertible<_Up*, _Tp*>::value &&
                                      is_same<_Dp, default_delete<_Tp> >::value,
                                      __nat
                                  >::type = __nat()) _NOEXCEPT
            : __ptr_(__p.release())
            {
            }

        _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT
            {
                reset(__u.release());
                __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
                return *this;
            }

        template <class _Up, class _Ep>
            _LIBCPP_INLINE_VISIBILITY
            typename enable_if
            <
                !is_array<_Up>::value &&
                is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value &&
                is_assignable<deleter_type&, _Ep&&>::value,
                unique_ptr&
            >::type
            operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
            {
                reset(__u.release());
                __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
                return *this;
            }
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES

    _LIBCPP_INLINE_VISIBILITY operator __rv<unique_ptr>()
    {
        return __rv<unique_ptr>(*this);
    }

    _LIBCPP_INLINE_VISIBILITY unique_ptr(__rv<unique_ptr> __u)
        : __ptr_(__u->release(), _VSTD::forward<deleter_type>(__u->get_deleter())) {}

    template <class _Up, class _Ep>
    _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(unique_ptr<_Up, _Ep> __u)
    {
        reset(__u.release());
        __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
        return *this;
    }

    _LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, deleter_type __d)
        : __ptr_(_VSTD::move(__p), _VSTD::move(__d)) {}

    template <class _Up>
        _LIBCPP_INLINE_VISIBILITY
                typename enable_if<
                                      is_convertible<_Up*, _Tp*>::value &&
                                      is_same<_Dp, default_delete<_Tp> >::value,
                                      unique_ptr&
                                  >::type
        operator=(auto_ptr<_Up> __p)
            {reset(__p.release()); return *this;}

#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    _LIBCPP_INLINE_VISIBILITY ~unique_ptr() {reset();}

    _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(nullptr_t) _NOEXCEPT
    {
        reset();
        return *this;
    }

    _LIBCPP_INLINE_VISIBILITY typename add_lvalue_reference<_Tp>::type operator*() const
        {return *__ptr_.first();}
    _LIBCPP_INLINE_VISIBILITY pointer operator->() const _NOEXCEPT {return __ptr_.first();}
    _LIBCPP_INLINE_VISIBILITY pointer get() const _NOEXCEPT {return __ptr_.first();}
    _LIBCPP_INLINE_VISIBILITY       _Dp_reference get_deleter() _NOEXCEPT
        {return __ptr_.second();}
    _LIBCPP_INLINE_VISIBILITY _Dp_const_reference get_deleter() const _NOEXCEPT
        {return __ptr_.second();}
    _LIBCPP_INLINE_VISIBILITY
        _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT
        {return __ptr_.first() != nullptr;}

    _LIBCPP_INLINE_VISIBILITY pointer release() _NOEXCEPT
    {
        pointer __t = __ptr_.first();
        __ptr_.first() = pointer();
        return __t;
    }

    _LIBCPP_INLINE_VISIBILITY void reset(pointer __p = pointer()) _NOEXCEPT
    {
        pointer __tmp = __ptr_.first();
        __ptr_.first() = __p;
        if (__tmp)
            __ptr_.second()(__tmp);
    }

    _LIBCPP_INLINE_VISIBILITY void swap(unique_ptr& __u) _NOEXCEPT
        {__ptr_.swap(__u.__ptr_);}
};

 

参考libstdc++-v3/include/bits/unique_ptr.h

  template <typename _Tp, typename _Dp = default_delete<_Tp>>
    class unique_ptr
    {
      template <typename _Up>
	using _DeleterConstraint =
	  typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;

      __uniq_ptr_data<_Tp, _Dp> _M_t;

    public:
      using pointer	  = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
      using element_type  = _Tp;
      using deleter_type  = _Dp;

    private:
      // helper template for detecting a safe conversion from another
      // unique_ptr
      template<typename _Up, typename _Ep>
	using __safe_conversion_up = __and_<
	  is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
	  __not_<is_array<_Up>>
        >;

    public:
      // Constructors.

      /// Default constructor, creates a unique_ptr that owns nothing.
      template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
	constexpr unique_ptr() noexcept
	: _M_t()
	{ }

      /** Takes ownership of a pointer.
       *
       * @param __p  A pointer to an object of @c element_type
       *
       * The deleter will be value-initialized.
       */
      template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
	_GLIBCXX23_CONSTEXPR
	explicit
	unique_ptr(pointer __p) noexcept
	: _M_t(__p)
        { }

      /** Takes ownership of a pointer.
       *
       * @param __p  A pointer to an object of @c element_type
       * @param __d  A reference to a deleter.
       *
       * The deleter will be initialized with @p __d
       */
      template<typename _Del = deleter_type,
	       typename = _Require<is_copy_constructible<_Del>>>
	_GLIBCXX23_CONSTEXPR
	unique_ptr(pointer __p, const deleter_type& __d) noexcept
	: _M_t(__p, __d) { }

      /** Takes ownership of a pointer.
       *
       * @param __p  A pointer to an object of @c element_type
       * @param __d  An rvalue reference to a (non-reference) deleter.
       *
       * The deleter will be initialized with @p std::move(__d)
       */
      template<typename _Del = deleter_type,
	       typename = _Require<is_move_constructible<_Del>>>
	_GLIBCXX23_CONSTEXPR
	unique_ptr(pointer __p,
		   __enable_if_t<!is_lvalue_reference<_Del>::value,
				 _Del&&> __d) noexcept
	: _M_t(__p, std::move(__d))
	{ }

      template<typename _Del = deleter_type,
	       typename _DelUnref = typename remove_reference<_Del>::type>
	_GLIBCXX23_CONSTEXPR
	unique_ptr(pointer,
		   __enable_if_t<is_lvalue_reference<_Del>::value,
				 _DelUnref&&>) = delete;

      /// Creates a unique_ptr that owns nothing.
      template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
	constexpr unique_ptr(nullptr_t) noexcept
	: _M_t()
	{ }

      // Move constructors.

      /// Move constructor.
      unique_ptr(unique_ptr&&) = default;

      /** @brief Converting constructor from another type
       *
       * Requires that the pointer owned by @p __u is convertible to the
       * type of pointer owned by this object, @p __u does not own an array,
       * and @p __u has a compatible deleter type.
       */
      template<typename _Up, typename _Ep, typename = _Require<
               __safe_conversion_up<_Up, _Ep>,
	       __conditional_t<is_reference<_Dp>::value,
			       is_same<_Ep, _Dp>,
			       is_convertible<_Ep, _Dp>>>>
	_GLIBCXX23_CONSTEXPR
	unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
	: _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
	{ }

#if _GLIBCXX_USE_DEPRECATED
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
      /// Converting constructor from @c auto_ptr
      template<typename _Up, typename = _Require<
	       is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
	unique_ptr(auto_ptr<_Up>&& __u) noexcept;
#pragma GCC diagnostic pop
#endif

      /// Destructor, invokes the deleter if the stored pointer is not null.
#if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
      constexpr
#endif
      ~unique_ptr() noexcept
      {
	static_assert(__is_invocable<deleter_type&, pointer>::value,
		      "unique_ptr's deleter must be invocable with a pointer");
	auto& __ptr = _M_t._M_ptr();
	if (__ptr != nullptr)
	  get_deleter()(std::move(__ptr));
	__ptr = pointer();
      }

      // Assignment.

      /** @brief Move assignment operator.
       *
       * Invokes the deleter if this object owns a pointer.
       */
      unique_ptr& operator=(unique_ptr&&) = default;

      /** @brief Assignment from another type.
       *
       * @param __u  The object to transfer ownership from, which owns a
       *             convertible pointer to a non-array object.
       *
       * Invokes the deleter if this object owns a pointer.
       */
      template<typename _Up, typename _Ep>
	_GLIBCXX23_CONSTEXPR
        typename enable_if< __and_<
          __safe_conversion_up<_Up, _Ep>,
          is_assignable<deleter_type&, _Ep&&>
          >::value,
          unique_ptr&>::type
	operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
	{
	  reset(__u.release());
	  get_deleter() = std::forward<_Ep>(__u.get_deleter());
	  return *this;
	}

      /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
      _GLIBCXX23_CONSTEXPR
      unique_ptr&
      operator=(nullptr_t) noexcept
      {
	reset();
	return *this;
      }

      // Observers.

      /// Dereference the stored pointer.
      _GLIBCXX23_CONSTEXPR
      typename add_lvalue_reference<element_type>::type
      operator*() const noexcept(noexcept(*std::declval<pointer>()))
      {
	__glibcxx_assert(get() != pointer());
	return *get();
      }

      /// Return the stored pointer.
      _GLIBCXX23_CONSTEXPR
      pointer
      operator->() const noexcept
      {
	_GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
	return get();
      }

      /// Return the stored pointer.
      _GLIBCXX23_CONSTEXPR
      pointer
      get() const noexcept
      { return _M_t._M_ptr(); }

      /// Return a reference to the stored deleter.
      _GLIBCXX23_CONSTEXPR
      deleter_type&
      get_deleter() noexcept
      { return _M_t._M_deleter(); }

      /// Return a reference to the stored deleter.
      _GLIBCXX23_CONSTEXPR
      const deleter_type&
      get_deleter() const noexcept
      { return _M_t._M_deleter(); }

      /// Return @c true if the stored pointer is not null.
      _GLIBCXX23_CONSTEXPR
      explicit operator bool() const noexcept
      { return get() == pointer() ? false : true; }

      // Modifiers.

      /// Release ownership of any stored pointer.
      _GLIBCXX23_CONSTEXPR
      pointer
      release() noexcept
      { return _M_t.release(); }

      /** @brief Replace the stored pointer.
       *
       * @param __p  The new pointer to store.
       *
       * The deleter will be invoked if a pointer is already owned.
       */
      _GLIBCXX23_CONSTEXPR
      void
      reset(pointer __p = pointer()) noexcept
      {
	static_assert(__is_invocable<deleter_type&, pointer>::value,
		      "unique_ptr's deleter must be invocable with a pointer");
	_M_t.reset(std::move(__p));
      }

      /// Exchange the pointer and deleter with another object.
      _GLIBCXX23_CONSTEXPR
      void
      swap(unique_ptr& __u) noexcept
      {
	static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
	_M_t.swap(__u._M_t);
      }

      // Disable copy from lvalue.
      unique_ptr(const unique_ptr&) = delete;
      unique_ptr& operator=(const unique_ptr&) = delete;
  };

示例

#include <iostream>  
#include <memory>  

int main()  
{  
  int *i = new int(100);  
  std::unique_ptr<int> p(i);  	
  	
  std::cout<<"i="<<*p<<std::endl;
  return 0;
}

 

shared_ptr

template<class T>
class shared_ptr
{
public:
    typedef T element_type;

    // constructors:
    constexpr shared_ptr() noexcept;
    template<class Y> explicit shared_ptr(Y* p);
    template<class Y, class D> shared_ptr(Y* p, D d);
    template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
    template <class D> shared_ptr(nullptr_t p, D d);
    template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
    template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept;
    shared_ptr(const shared_ptr& r) noexcept;
    template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
    shared_ptr(shared_ptr&& r) noexcept;
    template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
    template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
    template<class Y> shared_ptr(auto_ptr<Y>&& r);
    template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
    shared_ptr(nullptr_t) : shared_ptr() { }

    // destructor:
    ~shared_ptr();

    // assignment:
    shared_ptr& operator=(const shared_ptr& r) noexcept;
    template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
    shared_ptr& operator=(shared_ptr&& r) noexcept;
    template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r);
    template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r);
    template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);

    // modifiers:
    void swap(shared_ptr& r) noexcept;
    void reset() noexcept;
    template<class Y> void reset(Y* p);
    template<class Y, class D> void reset(Y* p, D d);
    template<class Y, class D, class A> void reset(Y* p, D d, A a);

    // observers:
    T* get() const noexcept;
    T& operator*() const noexcept;
    T* operator->() const noexcept;
    long use_count() const noexcept;
    bool unique() const noexcept;
    explicit operator bool() const noexcept;
    template<class U> bool owner_before(shared_ptr<U> const& b) const;
    template<class U> bool owner_before(weak_ptr<U> const& b) const;
};

 

weak_ptr

 

template<class T>
class weak_ptr
{
public:
    typedef T element_type;

    // constructors
    constexpr weak_ptr() noexcept;
    template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
    weak_ptr(weak_ptr const& r) noexcept;
    template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
    weak_ptr(weak_ptr&& r) noexcept;                      // C++14
    template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // C++14

    // destructor
    ~weak_ptr();

    // assignment
    weak_ptr& operator=(weak_ptr const& r) noexcept;
    template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
    template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
    weak_ptr& operator=(weak_ptr&& r) noexcept;                      // C++14
    template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // C++14

    // modifiers
    void swap(weak_ptr& r) noexcept;
    void reset() noexcept;

    // observers
    long use_count() const noexcept;
    bool expired() const noexcept;
    shared_ptr<T> lock() const noexcept;
    template<class U> bool owner_before(shared_ptr<U> const& b) const;
    template<class U> bool owner_before(weak_ptr<U> const& b) const;
};

 

  • 大小: 23.4 KB
分享到:
评论

相关推荐

    c++智能指针的创建

    C++智能指针的创建 C++中的指针是很麻烦的,难以管理和释放内存。为了减少问题的出现,现在有很多技巧去减少问题的出现。智能指针是其中一种解决方案。 智能指针是一种特殊的类,它可以模拟指针的行为,但同时也...

    C++智能指针-unique-ptr智能指针详解.pdf

    《C++智能指针——unique_ptr智能指针详解》 智能指针是C++中用于自动管理动态分配内存的一种工具,它可以确保在适当的时候自动释放内存,从而避免内存泄漏的问题。其中,`unique_ptr`是一种特殊的智能指针,它拥有...

    C++智能指针测试代码

    C++ 7种智能指针测试代码

    c++智能指针最全知识点即面试题目总结

    对于需要面试C++相关岗位的文章,看完这篇文章,如果面试官再问你智能指针,我敢肯定,你一定可以侃侃而谈了~智能指针的面试题,只看这一篇就够了!相信看完这篇文章,妈妈再也不用担心面试官考我智能指针的问题啦...

    C++智能指针:shared-ptr用法详解.pdf

    **C++智能指针shared_ptr详解** C++11引入了一种新的智能指针类型——`shared_ptr`,用于管理动态分配的对象。`shared_ptr`是C++标准库中的一个关键组件,它解决了传统裸指针可能导致的内存泄漏问题。通过使用`...

    c++智能指针的实现

    智能指针是用来实现指针指向的对象的共享的。其实现的基本思想: 每次创建类的新对象时,初始化指针并将引用计数置为1; 当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数; 对一个...

    C++智能指针(含内存计数)

    在C++编程中,智能指针是一种特殊类型的对象,它表现得像常规指针,但自动管理所指向的对象的生命周期。智能指针的核心目标是防止内存泄漏,这是C++编程中一个常见的问题,尤其是在处理动态分配的内存时。内存泄漏指...

    C++智能指针实现

    智能指针是存储指向动态分配(堆)对象指针的类, 用于生存期控制, 能够确保自动正确的销毁动态分配的对象,防止内存泄露。它的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的...

    C++线程安全问题及解决方法,C++智能指针

    对于C++智能指针作出了简要介绍。同时整理了相关的例子帮助理解。适用人群:有一定的编程基础,工作1-3年的研发人员。能学到什么:了解C++线程安全问题的原因,以及掌握解决线程安全问题的方法。同时能够掌握一下锁...

    C++智能指针详解abc

    C++智能指针详解 标题解释 "C++智能指针详解abc"这一标题表明,本文将详细介绍C++中的智能指针机制,包括其概述、原理、使用方法和结论等方面。 描述解释 "C++智能指针详解abc"这一描述表明,本文将对C++中的智能...

    c++智能指针介绍的PPT

    讲解的很清楚,将智能指针的精华所在详细说明,增加理解智能指针。

    C++ 智能指针(shared_ptr/weak_ptr)源码

    C++ 智能指针(shared_ptr/weak_ptr)源码 源码位置:gcc-6.1.0\gcc-6.1.0\libstdc++-v3\include\tr1 这里只单列shared_ptr.h文件用于分析

    【讨论】c++智能指针

    【C++ 智能指针详解】 C++ 智能指针是C++标准库提供的一种对象,它能够自动管理动态分配的内存,从而避免内存泄漏的问题。智能指针通过模仿原始指针的行为,同时附加了一套规则来确保在适当的时候释放内存。在C++中...

    C++智能指针 学习手册

    C++ 智能指针C++ 智能指针C++ 智能指针

    C++智能指针

    C++ 中推出了强大的智能指针smart_ptr ,本文具体说说 shared_ptr 和 weak_ptr ,特别是 enable_shared_from_this 和 shared_from_this

    C++智能指针(1).pdf

    C++智能指针是C++语言为解决内存管理问题,特别是防止内存泄漏而引入的一种机制。传统的C++中,程序员需要手动申请和释放内存,这可能导致内存泄漏,尤其是在复杂的程序结构中。为了解决这个问题,C++引入了智能指针...

    C++ 智能指针实现

    ### C++智能指针实现详解 #### 引言:智能指针在C++中的角色 在C++编程语言中,动态内存管理是一项复杂且容易出错的任务,这往往是导致运行时错误的主要原因之一。错误类型多样,包括但不限于内存泄漏、过早释放...

Global site tag (gtag.js) - Google Analytics