C++智能指针实现及改进

来源:互联网 发布:sql server2000下载 编辑:程序博客网 时间:2024/05/22 08:48

      最近研究了一些智能指针的实现,基本都是基于引用计数的。但是网上的代码基本有同一个问题就是重复析构。如:C++面试题(四)——智能指针的原理和实现 和 C++中智能指针的工作原理和简单实现 都是这样的问题,用测试代码:

int main()   {  int *p=new int(2);    SmartPointer<int> p1=p; SmartPointer<int> p2=p;SmartPointer<int> p3;p3=p1;return 0;}  
在VC6.0中必然会在返回时出现程序崩溃的错误。(PS:不过用c-free5 gcc5.0编译器居然不会报错,貌似有安全机制重复释放的时候自动处理了)

言归正传,为了解决上述问题我对智能指针的类进行了升级,加入了全局映射表,保证每个地址的引用计数唯一,基本实现了安全使用。


文件名:SmartPtr.h

#include <map>typedef std::map<void*, size_t*> SmartMap; //定义智能指针映射表类型template <typename T>class CSmartPtr{public://构造函数CSmartPtr(T* pPtr = NULL): _ptr(pPtr){if (pPtr){//添加指针到映射表AddSmartPtr(pPtr);}}//拷贝构造CSmartPtr(const CSmartPtr &src){if (this != &src){//添加指针到映射表AddSmartPtr(src._ptr);_ptr = src._ptr;}}//重载赋值操作符CSmartPtr& operator=(const CSmartPtr &src){if (_ptr == src._ptr){return *this;}//由于左值指向了其他地址,故引用计数减1RemoveSmartPtr(_ptr);//将右值加入到指针映射表中AddSmartPtr(src._ptr);_ptr = src._ptr;return *this;}//重载基本操作符T& operator *(){return *_ptr;}T* operator ->(){return _ptr;}//析构函数~CSmartPtr(){RemoveSmartPtr(_ptr);}private:T *_ptr;static SmartMap _pSmartMap; //类的全局指针映射表  保存参数:指针地址,引用计数地址void AddSmartPtr(T *pPtr){SmartMap::iterator it;it = _pSmartMap.find((void*)pPtr); //查找映射表if (it != _pSmartMap.end()){++(*it->second);  //表中存在该地址,则引用计数加1return;}size_t *ref = new size_t(1);  //初始引用计数设置为1_pSmartMap.insert(SmartMap::value_type((void*)pPtr, ref)); //表中不存在,则添加到映射表中}void RemoveSmartPtr(T *pPtr){SmartMap::iterator it;it = _pSmartMap.find((void*)pPtr);if (it != _pSmartMap.end()){if (--(*(it->second)) == 0)  //引用计数为0,则删除对象{delete(T*)it->first;delete it->second;_pSmartMap.erase(it);return;}}}};//初始化类的静态变量template <typename T>SmartMap CSmartPtr<T>::_pSmartMap;

     大家在使用的时候,包含一下头文件即可,VC6.0下测试运行良好。

    测试代码如下:

int main(int argc, char* argv[]){int *p = new int(2);CSmartPtr<int> p1 = p;CSmartPtr<int> p2 = p;CSmartPtr<int> p3;p3 = p1;return 0;}