实现一个简单的智能指针
昨天在看牛客网上一道题,实现一个简单的智能指针,发现写出来有困难,之前也一直没有实现过。
智能指针是一种资源管理类,通过对原始指针进行封装,在资源管理对象进行析构时对指针指向的内存进行释放;通常使用引用计数方式进行内存管理。一个基本的实现如下:
#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对象,就不会被析构。出现内存泄漏。