实现一个简单的智能指针

昨天在看牛客网上一道题,实现一个简单的智能指针,发现写出来有困难,之前也一直没有实现过。

智能指针是一种资源管理类,通过对原始指针进行封装,在资源管理对象进行析构时对指针指向的内存进行释放;通常使用引用计数方式进行内存管理。一个基本的实现如下:

#include <iostream>
#include <string>
using namespace std;

void play();

template<typename T>
class Share{
public:
    friend void play();
    Share() :ptr(0), cnt(new int(0)) {}
    Share(T* p)
    {
        ptr = p;
        if (cnt == NULL)
        {
            cnt = new int(1);
        }
    }
    Share(Share& sp)
    {
        ptr = sp.ptr;
        (*(sp.cnt))++;
        cnt = sp.cnt;   //使它们执行指向同一个地址空间,实现共享

    }
    ~Share()
    {
        //cout << "begin to delete share" << endl;
        if (--(*cnt)== 0)
        {
            delete ptr;
            ptr = NULL;
            cout << "begin to delete share" << endl;
        }
        //cout << *cnt << endl;
    }

    Share& operator =(Share& sp)
    {
        //可以应对自我赋值
        if (--(*cnt) == 0)
            delete ptr;
        ptr = sp.ptr;
        sp.(*cnt)++;
        cnt = sp.cnt;    //使它们指向同一个地址空间,实现数据共享
        return *this;
    }

    //注意 :一定要重载运算符(->)哦
    T* operator ->()
    {
        return ptr;
    }
private:
    T* ptr;
    int* cnt;  //这里一定是指针,这样才能被共享
};


class A{
public:
    A() :n(0)
    {
        cout << "A constrctor" << endl;
    }
    ~A()
    {
        cout << "A destroy" << endl;
    }

    int n;
};

void play()
{
    A* pa = new A();
    Share<A>sp(pa);
    sp->n = 10;         //如果不重载->运算符,这里就不能实现    (智能指针是重载了->的)

    Share<A>sp2 = sp;
}

int main()
{
    play();
    system("pause");
    return 0;
}

输出如下:

 

注意:

在Share类中的计数成员 cnt  一定是int* 型。为什么不能是int 型呢?

因为如果为int型,那么在  

void play()
{
A* pa = new A();
Share<A>sp(pa);
sp->n = 10;

Share<A>sp2 = sp;
}

这个函数中,sp2和sp1中的cnt=2,假设函数执行完后,sp先析构,那么,sp的cnt变成了1,而sp2的并没有变,还是2(以为他们不是同一个地址),这样最后sp和sp2的cnt都是1,那么在析构函数中都不会调用  delete ptr。那么 A pa对象,就不会被析构。出现内存泄漏。

posted @ 2017-04-10 21:20  ren_zhg1992  阅读(405)  评论(0编辑  收藏  举报