天天看点

boost库的shared_ptr剖析

shared_ptr其实就是一个模板类。

shared_ptr是Boost里面最有价值的的智能指针。它封装了一个原生态指针和一个引用计数器,这个引用计数器是一个类shared_count。shared_ptr支持比较运算,重载了operator<,因此其可以用于set和map。

shared_ptr的应用:当shared_ptr指针指向了一个对象,之后又有另一个shared_ptr指针指向了那个对象,那么这个指针的计数变成了二,当析构了原先的指针,那么指针的计数就变成了1(因为使用的是循环引用,所以有循环计数问题,为了打破循环,可以使用weak_ptr去跳出循环)每一个shared_ptr的拷贝都指向了相同的内存,只有在最后一个被析构的时候他的内存才会被释放。

对于shared_ptr的深入理解:      

线程安全:

1.一个shared_ptr实体可以被多个线程同时读取

2.两个shared_ptr实体可以被两个线程同时写入,“析构”算写操作

3.如果要从多个线程读写同一个shared_ptr对象,那么需要加锁

关于函数的框架

namespace boost {

  class bad_weak_ptr: public std::exception;

  template<class T> class weak_ptr;

  template<class T> class shared_ptr {

    public:

      typedef see below element_type;//重定义元素类型,当指针指向单个元素那么元素类型是T,当指针指向数组那么元素类型是U

      shared_ptr(); // never throws构造函数
      shared_ptr(std::nullptr_t); // never throws

      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(std::nullptr_t p, D d);
      template<class D, class A> shared_ptr(std::nullptr_t p, D d, A a);

      ~shared_ptr(); // never throws析构函数

      shared_ptr(shared_ptr const & r); // never throws
      template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws

      shared_ptr(shared_ptr && r); // never throws
      template<class Y> shared_ptr(shared_ptr<Y> && r); // never throws

      template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p); // never throws

      template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);

      template<class Y> explicit shared_ptr(std::auto_ptr<Y> & r);
      template<class Y> shared_ptr(std::auto_ptr<Y> && r);

      template<class Y, class D> shared_ptr(std::unique_ptr<Y, D> && r);      
/上面是各种形式的智能指针的构造函数,因为shared_ptr针对的是所有类型的对象或者元素//

      shared_ptr & operator=(shared_ptr const & r); // never throws
      template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r); // never throws

      shared_ptr & operator=(shared_ptr const && r); // never throws
      template<class Y> shared_ptr & operator=(shared_ptr<Y> const && r); // never throws

      template<class Y> shared_ptr & operator=(std::auto_ptr<Y> & r);
      template<class Y> shared_ptr & operator=(std::auto_ptr<Y> && r);

      template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y, D> && r);

      shared_ptr & operator=(std::nullptr_t); // never throws
//全部是对于赋值符号的重载/
      void reset(); // never throws

      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);

      template<class Y> void reset(shared_ptr<Y> const & r, element_type * p); // never throws

      
//对于重置的重载///      
T & operator*() const; // never throws; only valid when T is not an array type
      T * operator->() const; // never throws; only valid when T is not an array type

      element_type & operator[](std::ptrdiff_t i) const; // never throws; only valid when T is an array type

      element_type * get() const; // never throws

      bool unique() const; // never throws
      long use_count() const; // never throws

      explicit operator bool() const; // never throws

      void swap(shared_ptr & b); // never throws
      
      template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const; // never throws
      template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const; // never throws      
关于内部各种符号的重载和需要的函数///
  };

  template<class T, class U>
    bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws

  template<class T, class U>
    bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws

  template<class T, class U>
    bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws

  template<class T>
    bool operator==(shared_ptr<T> const & p, std::nullptr_t); // never throws

  template<class T>
    bool operator==(std::nullptr_t, shared_ptr<T> const & p); // never throws

  template<class T>
    bool operator!=(shared_ptr<T> const & p, std::nullptr_t); // never throws

  template<class T>
    bool operator!=(std::nullptr_t, shared_ptr<T> const & p); // never throws

      
//对于智能指针比较的重载///      
template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b); // never throws

  template<class T> typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p); // never throws

  template<class T, class U>
    shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r); // never throws

  template<class T, class U>
    shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r); // never throws

  template<class T, class U>
    shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r); // never throws

  template<class T, class U>
    shared_ptr<T> reinterpet_pointer_cast(shared_ptr<U> const & r); // never throws

  template<class E, class T, class Y>
    std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);

  template<class D, class T>
    D * get_deleter(shared_ptr<T> const & p);
}      
shared_ptr指针在线程中的作用:      
1 同一个shared_ptr被多个线程“读”是安全的。      
2 同一个shared_ptr被多个线程“写”是不安全的。       
3 共享引用计数的不同的shared_ptr被多个线程”写“ 是安全的。       
看完boost库关于shared_ptr的源代码以及官方文档之后我的感觉就是shared_ptr如果以C++的思想来看它就是一个模板类,实现的是对所有的类型(包括双参数map等)的一个指针引用,他的拷贝其实就是多一个指针指向原先的内存地址,当使用reset的时候他的计数减一,当是最后一个智能指针的时候再使用reset就析构成功了,注意的是shared_ptr和weak_ptr一样,都是使用px表示所指对象的类型,pn表示有几份指针指向了这个对象。      

继续阅读