关闭

【C++】智能指针的原始写法、scoped写法、shared写法

77人阅读 评论(0) 收藏 举报
分类:

  智能指针的三种常见写法:

  一、最开始的原始写法,原始写法可以理解为指针转移的方法。

template<typename T>
class AutoPtr
{
public:
    AutoPtr()
        :_ptr(NULL)
    {}

    AutoPtr(T* ptr)
        :_ptr(ptr)
    {}

    ~AutoPtr()
    {
        if (_ptr)
        {
            delete _ptr;
            _ptr = NULL;
        }
    }

    AutoPtr<T>(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;
    }


    T& operator*()
    {
        return *_ptr;

    }

    T* GerPtr()
    {
        return _ptr;
    }
private:
    T* _ptr;
};

  二、演变为后来的scoped写法,又可以称作守卫写法。该写法相对于原始写法的优点在于不让使用拷贝构造和运算符的重载,这样就避免了深浅拷贝的指针问题。做法是把拷贝构造、运算符的重载定声明出来而不定义,并且用protected保护起来。scoped写法是引用的boost库。有兴趣的可以去了解一下这个东西,背后还是有很多故事的,在这我就不多说啦。

template<class T>
class scopedPtr
{
public:
    scopedPtr()
        :_ptr(NULL)
    {}

    scopedPtr(T* ptr)
        :_ptr(ptr)
    {}

    ~scopedPtr()
    {
        if (_ptr)
        {
            delete _ptr;
            _ptr = NULL;
        }
    }
    
    T& operator*()
    {
        return *_ptr;
    }

    T* operator->()
    {
        return _ptr;
    }

    T* GetPtr()
    {
        return _ptr;
    }

protected: //加上protected可以防止使用者在类之外定义拷贝构造和运算符的重载函数
    scopedPtr<T>(const scopedPtr<T>& sp);        //不让使用者使用拷贝,可以防止拷贝,所以只声明不定义
    scopedPtr<T>& operator=(const scopedPtr<T>& sp);

private:
    T* _ptr;
};

  三、sharedPtr写法

这种方法考虑了深浅拷贝问题并且引用了引用计数器来解决浅拷贝的问题,比较完善的实现了智能指针想要实现的功能。

template<class T>
class SharePtr
{
public:
    SharePtr(T* ptr)
        :_ptr(ptr)
        , _pCount(new int(1))
    {}

    //SharePtr(Shar)
    //    :_ptr(sp._ptr)
    //{
    //    *_pCount = 1;
    //}

    ~SharePtr()
    {
        if (_ptr)
        {
            if (--(*_pCount) == 0)
            {
                delete _ptr;
                delete _pCount;
                _ptr = NULL;
                _pCount = NULL;
            }

            _ptr = NULL;
        }
    }

    SharePtr<T>(const SharePtr<T>& sp)
    {
        _ptr = sp._ptr;
        _pCount = sp._pCount;
        ++(*_pCount);
    }

    SharePtr<T>& operator=(const SharePtr<T>& sp)
    {
        if (this != &sp)
        {
            if (--(*_pCount) == 0)    //这里要分清楚是谁减一,逻辑需要分析清楚
            {
                delete _ptr;
                delete _pCount;
                _ptr = NULL;
                _pCount = NULL;
            }

            _ptr = sp._ptr;
            _pCount = sp._pCount;
            ++(*_pCount);
        }
        return *this;
    }

private:
    T* _ptr;
    int* _pCount;
};


本文出自 “滴水” 博客,请务必保留此出处http://10740329.blog.51cto.com/10730329/1766046

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:16158次
    • 积分:218
    • 等级:
    • 排名:千里之外
    • 原创:109篇
    • 转载:7篇
    • 译文:0篇
    • 评论:1条
    文章分类
    最新评论