一. 实现版本v3
- 引用计数技术:
引用计数需要存储在被引用的资源对象里,一个资源对象对应一个引用计数, 当其引用计数为0时,资源对象可以被销毁。
需要修改以下函数中实现计数功能:
- 接收不同对象类型的构造函数:这个构造函数实现,比较简单,直接将引用计数加1 即可
- 析构函数:析构函数的实现,不能再直接做delete操作,而是需要先对引用计数减1,当引用计数为0时,才做delete操作。
- 拷贝构造函数:拷贝构造函数的实现,底层指针共享,然后将引用计数加1 即可。
- 赋值操作符:赋值操作的实现,稍微复杂一些,涉及到将新指向对象的引用计数加1,将原指向对象的引用计数减1,如果有需要还要销毁原指向对象。这里有一点值得注意的地方,我们新的赋值操作的实现,不再需要if (this == &other) return *this;语句处理自我赋值的情况,读者可自行分析一下我们新的赋值操作的实现为何不需要通过if语句去处理自我赋值的情况。
- 引用计数基类
一般按照面向对象的设计方法,我们会将管理引用计数的相关内容,抽象成一个基类,这样任何期望能够被智能指针引用的资源类,只要继承该类即可。
- 头文件 smartpointer.h
/* * file name : smartpointer.h * desp : 智能指针版本v3 */ #ifndef __SMARTPOINTER_H__ #define __SMARTPOINTER_H__ template <typename T> // 将智能指针类定义成模板类 class SmartPointer { public: // 默认构造函数 SmartPointer():mPointer(NULL) {std::cout <<"Create null smart pointer."<< std::endl;} // 接收不同对象类型的构造函数 SmartPointer(T *p):mPointer(p) { std::cout <<"Create smart pointer at "<<static_cast<const void*>(p)<<std::endl; /*智能指针指向类T,引用计数加1*/ if (mPointer) mPointer->incRefCount(); } // 析构函数 ~SmartPointer(){ std::cout << "Release smart pointer at "<<static_cast<const void*>(mPointer)<<std::endl; // 实现内存资源自动销毁机制 if (mPointer && mPointer->decRefCount()==0) delete mPointer; } // 拷贝构造函数 SmartPointer(const SmartPointer &other):mPointer(other.mPointer) { std::cout <<"Copy smart pointer at "<<static_cast<const void*>(other.mPointer)<<std::endl; // 引用计数加1 if(mPointer) mPointer->incRefCount(); } // 赋值操作符 SmartPointer &operator = (const SmartPointer &other) { T *temp(other.mPointer); // 新指向对象,引用计数值加1 if (temp) temp->incRefCount(); // 原指向对象,引用计数值减1,如果减1后引用计数为0 销毁原资源对象 if (mPointer && mPointer->decRefCount()==0) delete mPointer; // 智能指针指向新资源对象 mPointer = temp; return *this; } private: T *mPointer; // 指向智能指针实际对应的内存资源,根据参数自动推导规则,定义内部资源指针类型 }; /*引用计数基类*/ class RefBase { public: RefBase() : mCount(0){ } void incRefCount(){ mCount++; } int decRefCount(){ return --mCount; } // 调试接口,返回对象当前引用计数 int getRefCount(){ return mCount; } virtual ~RefBase(){ } private: int mCount; }; #endif // __SMARTPOINTER_H__
- 测试文件 sptestcase3.cpp
/* * file name : sptestcase3.cpp * desp : 智能指针测试代码 case3 测试智能指针的引用计数功能 */ #include <iostream> #include "smartpointer.h" /*继承于引用计数基类的SomeClass类*/ class SomeClass: public RefBase{ public: SomeClass(){std::cout << "SomeClass default constructor !"<<std::endl;} ~SomeClass(){std::cout << "SomeClass deconstructor !"<<std::endl;} }; void testcase3(void) { SomeClass *pSomeClass = new SomeClass(); //1 SmartPointer<SomeClass> spOuter = pSomeClass; std::cout << "SomeClass Ref Count (" << pSomeClass->getRefCount() << ") outer 1."<< std::endl; { // inner 语句块 SmartPointer<SomeClass> spInner = spOuter; std::cout << "SomeClass Ref Count (" << pSomeClass->getRefCount() << ") inner."<< std::endl; } std::cout << "SomeClass Ref Count (" << pSomeClass->getRefCount() << ") outer 2."<< std::endl; // delete pSomeClass ; 不需要也不能执行delete操作! std::cout << "new another SomeClass class for spOuter."<< std::endl; SmartPointer<SomeClass> spOuter2 = new SomeClass(); spOuter = spOuter2;// 1处new出来的SomeClass将会被自动释放 } int main(void) { testcase3(); return 0; }
结果分析
- v3版本基本实现了智能指针功能,下一步可完善作为指针的功能:解引用、判空、比较操作
二. 知识点查漏补缺
- 野指针