代码改变世界

C++实现具有基本功能的智能指针

2016-08-27 16:53  shuaihanhungry  阅读(200)  评论(0编辑  收藏  举报

C++中的智能指针实际上是代理模式与RAII的结合。

自定义unique_ptr,主要是release()和reset()。代码如下。

#include <iostream>
using namespace std;

template<typename T>
class my_unique_ptr {
public:
    my_unique_ptr(T *p = 0): pointee(p) {};
    ~my_unique_ptr() {
        delete pointee;
    }
    T &operator * () const {
        return *pointee;
    }
    T *operator -> () const {
        return pointee;
    }
    T *get() {
        return pointee;
    }
    T *release() {
        T *oldPointee = pointee;
        pointee = 0;
        return oldPointee;
    }
    void reset(T *p = 0) {
        if(pointee != p) {
            delete pointee;
            pointee = p;
        }
    }
private:
    my_unique_ptr(const my_unique_ptr<T> &rhs);
    my_unique_ptr<T> &operator = (const my_unique_ptr<T> &rhs);

    T *pointee;
};

struct C {
    ~C() {
        cout << "destructor" << endl;
    };
    void print() {
        cout << "print" << endl;
    };
};

int main() {
    my_unique_ptr<C> u1;
    cout << u1.get() << endl; //0

    my_unique_ptr<C> u2(new C());
    u2->print(); //print

    my_unique_ptr<C> u3(u2.release());
    cout << u2.get() << endl; //0
    u3->print(); //print

    my_unique_ptr<C> u4;
    u4.reset(u3.release());
    cout << u3.get() << endl; //0
    u4->print(); //print

    return 0; //destructor
}

自定义shared_ptr,主要是引用计数,代码如下。

#include <iostream>
using namespace std;

template<typename T>
class my_shared_ptr {
public:
    my_shared_ptr(T *p = 0): pointee(p), count(new size_t(0)) {
        if(p) ++*count;
    };
    my_shared_ptr(const my_shared_ptr<T> &rhs): pointee(rhs.pointee), count(rhs.count) {
        ++*count;
    }
    my_shared_ptr<T> &operator = (const my_shared_ptr<T> &rhs) {
        if(&rhs != this) {
            decrease_count();

            pointee = rhs.pointee;
            count = rhs.count;
            ++*count;
        }
        return *this;
    }
    ~my_shared_ptr() {
        decrease_count();
    }
    size_t use_count() {
        return *count;
    }
    T &operator * () const {
        return *pointee;
    }
    T *operator -> () const {
        return pointee;
    }
private:
    void decrease_count() {
        if(--*count == 0) {
            delete pointee;
            delete count;
        }
    }

    T *pointee;
    size_t *count;
};

struct C {
    ~C() {
        cout << "destructor" << endl;
    };
    void print() {
        cout << "print" << endl;
    };
};

int main() {
    my_shared_ptr<C> p1;
    cout << "p1: " << p1.use_count() << endl; //p1: 0

    my_shared_ptr<C> p2(new C());
    cout << "p2: " << p2.use_count() << endl; //p2: 1

    my_shared_ptr<C> p3(p2);
    cout << "p3: " << p3.use_count() << endl; //p3: 2

    my_shared_ptr<C> p4 = p3;
    cout << "p4: " << p4.use_count() << endl; //p4: 3

    {
        my_shared_ptr<C> p5(p4);
        cout << "p5: " << p5.use_count() << endl; //p5: 4
    }

    cout << "p2: " << p2.use_count() << endl; //p2: 3
    cout << "p3: " << p3.use_count() << endl; //p3: 3
    cout << "p4: " << p4.use_count() << endl; //p4: 3

    (*p4).print(); //print
    p4->print(); //print

    return 0; //destructor
}