智能指针

介绍

c++里面的四个智能指针: auto_ptr, shared_ptr, weak_ptr, unique_ptr 其中后三个是c++11支持,并且第一个已经被c++11弃用。都包含在头文件 #include <memory> 中.

  1. std::auto_ptr
    其实现不是基于引用计数的,而是独占的,一个指针在同一时刻只能被一个对象拥有。因此,在出现复制操作时之前的对象内容会被销毁。
    因此,使用时需注意:
  • 尽量不要复制,如果赋值了则不能再使用之前的对象。
  • 不要当成参数传递
  • 不能放在 vector 等容器中。
  1. shared_ptr
    允许多个指针指向同一个对象

  2. unique_ptr
    独占所指向的对象

  3. weak_ptr
    它是一种弱引用,指向shared_ptr所管理的对象.

智能指针的模拟实现

  1. auto_ptr实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    template <typename T>
    class AutoPtr {
    public:
    AutoPtr(T* ptr) :_ptr(ptr) {}
    ~AutoPtr() {
    if (_ptr) {
    delete _ptr;
    }
    }
    AutoPtr(AutoPtr<T>& ap) :_ptr(ap._ptr) {
    ap._ptr = NULL;//管理权转移,原来ap的_ptr置空
    }
    AutoPtr<T>& operator=(AutoPtr<T>& ap) {
    if (this != &ap) {
    delete _ptr;
    _ptr = ap._ptr;
    ap._ptr = NULL;//管理权转移,原来ap的_ptr置空
    }
    return *this;
    }
    T& operator*() {
    return *_ptr;
    }
    T* operator->() {
    return _ptr;
    }
    private:
    T* _ptr;
    };
  2. shared_ptr实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    template <typename T>
    class SmartPtr;

    template <typename T>
    class U_Ptr {
    private:
    friend class SmartPtr<T>;
    U_Ptr(T *ptr) : p(ptr), count(1) { }
    ~U_Ptr() {
    delete p;
    }
    int count;
    T *p;
    };

    template <typename T>
    class SmartPtr {
    public:
    SmartPtr(T *ptr) : rp(new U_Ptr<T>(ptr)) { }
    SmartPtr(const SmartPtr<T> &sp) : rp(sp.rp) {
    ++rp->count;
    }
    SmartPtr &operator=(const SmartPtr<T> &rhs) {
    ++rhs.rp->count;
    if(--rp->count == 0) {
    delete rp;
    }
    rp = rhs.rp;
    return *this;
    }
    T &operator*() {
    return *(rp->p);
    }
    T *operator->() {
    return rp->p;
    }
    ~SmartPtr() {
    if(--rp->count == 0) {
    delete rp;
    } else {
    // cout << rp->count << endl;
    }
    }

    private:
    U_Ptr<T> *rp;
    };