C++ 比较烦恼的是内存的管理,new是简单,不够,delete偶尔就会忘记。或者说,出现,多个对象共享多一个内存,一个delete以后,导致其他也不能用的不良情况,所以就跑出了一个智能指针来进行管理。
设计需求:
1.该智能指针能接受各种类型的指针 -- 使用模板
2.智能指针需要知道该对象有多少个人在用他 -- 大家用的同一个计数器 int * num;
3.共同使用同一个内存 -- 数据指针 T * data;
ps:目前为线程不安全的实现,若要达到线程安全,需要使用一个共同的互斥变量。
#ifndef SHARE_PTR_H #define SHARE_PTR_Htemplate<typename T> class share_ptr{ private:T * data;int * num; public:/*** @brief 构造函数,通过传入的对象指针进行初始化,* 并将计数器置1*/share_ptr(T * t):data(t);/*** @brief 析构函数,判断当前对象是否为最后一个,* 是就delete,不是就计数减1*/~share_ptr();/*** @brief 拷贝构造函数,通过rhs的值赋值,* 并将计数器加1*/share_ptr(share_ptr<T>& rhs);/*** @brief 赋值,判断当前对象是否一致,* 是则返回,不是则析构之前的,并用现在的赋值,* 计数器加1*/share_ptr<T>& operator =( share_ptr<T>& rhs);/*** @brief 返回数据的引用*/T& operator *(){ return *data; } /*** @brief 返回数据的指针*/T* operator ->() { return data; } /*** @brief 获取当前有多少个共同使用者*/int count(){ return *num;} };#endif //SHARE_PTR_H
实现
#ifndef SHARE_PTR_H #define SHARE_PTR_H#include <stdio.h> #include <iostream>#ifdef _DEBUG #define DEBUG(fmt) printf (fmt) #else #define DEBUG(x) #endiftemplate<typename T> class share_ptr{ private:T * data;int * num; public:share_ptr(T * t):data(t){num = new int;*num = 1;DEBUG("share_ptr(T * t):data(t)\n");}~share_ptr(){if(*num>1){(*num)--;DEBUG("~share_ptr,num = k\n");}else{DEBUG("~share_ptr,num = 0\n");delete data;delete num;data = NULL;num = NULL;}}//拷贝构造share_ptr(share_ptr<T>& rhs){data = rhs.data;num = rhs.num;(*num)++;DEBUG("share_ptr(share_ptr<T>& rhs)\n");}//赋值share_ptr<T>& operator =( share_ptr<T>& rhs){if( data == rhs.data){DEBUG("share_prt<T>& operator=(share_ptr<T>& rhs)\n");return *this;}else{//判断本来指向的指针是否是最后一个,是的话,就delete掉,不是的话就*num--if(*num == 1){delete data;delete num;data = NULL;num = NULL;}else{ (*num)--; }data = rhs.data;num = rhs.num;(*num)++;}DEBUG("share_prt<T>& operator=(share_ptr<T>& rhs)\n");return *this;}T& operator *(){ return *data; } T* operator ->() { return data; } int count(){ return *num;} };#endif //SHARE_PTR_H
测试:
#include <iostream> #include <string> #include "share_ptr.h"using namespace std;int main(){{share_ptr<string> ps( new string("hello world") );cout << *ps <<" count:"<< ps.count() << endl;share_ptr<string> ps2(ps);cout << *ps2 <<" count:"<< ps2.count() << endl;share_ptr<string> ps3 = ps;cout << *ps3 <<" count:"<< ps2.count() << endl;ps2 = ps3;cout << *ps2 <<" count:"<< ps2.count() << endl;}system("pause");return 0; }