实现智能指针

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;

}

输出结果

20
20
2
3
2
3

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;

}

输出结果

20
1
2

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;

}

输出结果

20
1
2

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;


}

输出结果

1
2
2
3
1
4
4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值