实现智能指针

来源:互联网 发布:aplusvable知乎 编辑:程序博客网 时间:2024/06/10 19:07

AutoPtr

资源的转移不推荐使用。
旧库使用拥有者会导致野指针

实现代码

template <class T>class AutoPtr{public:    AutoPtr(T* p = NULL)        : _ptr(p)    {}    AutoPtr(AutoPtr<T>& ap)        :_ptr(ap._ptr)    {        ap._ptr = NULL;    }    AutoPtr<T>& operator=(AutoPtr<T>& ap)    {        if (this != &ap)        {            delete _ptr;            _ptr = ap._ptr;            ap._ptr = NULL;        }        return *this;    }    ~AutoPtr()    {        if (_ptr)        {            delete _ptr;            _ptr = NULL;        }    }    T* GetPtr()    {        return _ptr;    }    const T* GetPtr()const    {        return _ptr;    }    T& operator*()    {        return *_ptr;    }    const T& operator*()const    {        return *_ptr;    }    T* operator->()    {        return _ptr;    }    const T* operator->()const    {        return _ptr;    }private:    T* _ptr;};

测试用例

void Test_AutoPtr(){    /*      *  测试构造函数拷贝拷贝构造    */    AutoPtr<int> ap1(new int(20));    std::cout << *ap1  << std::endl;    AutoPtr<int> ap2(ap1);    std::cout << *ap2 << std::endl;    /*    * 测试 operator = 和 -> *    */    struct A    {        int a;        int b;    };    AutoPtr<A> ap3(new A);    ap3->a = 2;    ap3->b = 3;    std::cout << (*ap3).a << std::endl;    std::cout << (*ap3).b << std::endl;    AutoPtr<A> ap4;    ap4 = ap3;    std::cout << (*ap4).a << std::endl;    std::cout << (*ap4).b << std::endl;}

输出结果

20202323

ScopedPtr / Unique_ptr

unique_ptr 是 c++11 标识, ScopedPtr 是 boost库提供 还有ScopedAarray

实现代码

template <class T>class ScopedPtr{public:    ScopedPtr(T* p = NULL)        : _ptr(p)    {}    ~ScopedPtr()    {        if (_ptr)        {            delete _ptr;            _ptr = NULL;        }    }    T* operator->()    {        return _ptr;    }    const T* operator->()const    {        return _ptr;    }    T& operator*()    {        return *_ptr;    }    const T& operator*()const    {        return *_ptr;    }    T* GetPtr()    {        return _ptr;    }    const T* GetPtr()const    {        return _ptr;    }private:    ScopedPtr(const ScopedPtr<T>&);    ScopedPtr<T>& operator=(const ScopedPtr<T>&);private:    T* _ptr;};

测试用例

void Test_ScopedPtr(){    ScopedPtr<int> sp1(new int(20));    std::cout << *sp1 << std::endl;    //ScopedPtr<int> sp2(sp1); // error 拷贝构造函数为私有    ScopedPtr<int> sp3(new int(30));    //sp3 = sp1;               // error 赋值运算符私有 方式拷贝    struct A    {        int a;        int b;    };    ScopedPtr<A> sp4(new A);    sp4->a = 1;    sp4->b = 2;    std::cout << (*sp4).a << std::endl;    std::cout << (*sp4).b<< std::endl;}

输出结果

2012

ScopedArray

实现代码

template <class T>class ScopedArray{public:    ScopedArray(T* p = NULL)        : _ptr(p)    {}    ~ScopedArray()    {        if (_ptr)        {            delete[] _ptr;            _ptr = NULL;        }    }    T& operator[](size_t index)    {        return _ptr[index];    }    const T& operator[](size_t index)const    {        return _ptr[index];    }private:    ScopedArray(const ScopedArray<T>&);    ScopedArray<T>& operator=(const ScopedArray<T>&);private:    T* _ptr;};

测试用例

void Test_ScopedArray(){    ScopedArray<int> spa1(new int[10]);    spa1[0] = 20;    std::cout << spa1[0] << std::endl;    ScopedArray<int> spa2(new int[20]);    // spa2 = spa1;       // error ,operator = 为私有    // ScopedArray<int> spa3(spa1);  // error  拷贝构造为私有    struct A    {        int a;        int b;    };    ScopedArray<A> spa4(new A[10]);    spa4[0].a = 1;    spa4[0].b = 2;    std::cout << spa4[0].a << std::endl;    std::cout << spa4[0].b << std::endl;}

输出结果

2012

SharedPtr

存在的问题,循环引用,weak_ptr解决。他不会占用引用计数,必须用一个sharedptr来赋值。
shared 定制删除器。 C++11 提供了 shared_ptr。Boost提供了shared_ptr 和 sharedarray。

实现代码

template <class T>class SharedPtr{public:    explicit SharedPtr(T* p  = NULL)        : _ptr(p)        , _pcount(new unsigned int(1))    {}    explicit SharedPtr(const SharedPtr<T>& sp)        :_ptr(sp._ptr)        , _pcount(sp._pcount)    {        ++(*_pcount);    }    SharedPtr<T>& operator=(const SharedPtr<T>& sp)    {        if (this != &sp)        {            if ((--(*_pcount)) == 0)            {                delete _pcount;                delete _ptr;            }            _ptr = sp._ptr;            _pcount = sp._pcount;            ++(*_pcount);        }        return *this;    }    ~SharedPtr()    {        if ((--(*_pcount)) == 0)        {            delete _ptr;            delete _pcount;        }    }    unsigned int UseCount()const    {        return *_pcount;    }    T& operator*()    {        return *_ptr;    }    const T& operator*()const    {        return *_ptr;    }    T* operator->()    {        return _ptr;    }    const T* operator->()const    {        return _ptr;    }    T* GetPtr()    {        return _ptr;    }    const T* GetPtr()const    {        return _ptr;    }private:    T* _ptr;    unsigned int* _pcount;};

测试用例

void Test_ShareddPtr(){    SharedPtr<int> sp1(new int(2));    sp1 = sp1;    std::cout << sp1.UseCount() << std::endl;    std::cout << *sp1 << std::endl;    SharedPtr<int> sp2(sp1);    std::cout << sp1.UseCount() << std::endl;    SharedPtr<int> sp3;    sp3 = sp1;    std::cout << sp1.UseCount() << std::endl;    SharedPtr<int> sp4(new int(4));    std::cout << sp4.UseCount() << std::endl;    sp4 = sp1;    std::cout << sp4.UseCount() << std::endl;    std::cout << sp1.UseCount() << std::endl;}

输出结果

1223144