在看More Effective C++时就有引用计数,现在自己实现了下。
完成计数的基类
/**************************************************author:周翔*e-mail:604487178@qq.com*blog:http://blog.csdn.net/zhx6044***************************************************/#ifndef REFCOUNTER_H#define REFCOUNTER_H#include一个需要实现引用计数的类class RefCounter{public: RefCounter(); virtual ~RefCounter() = 0; void plusOneRef(); void minusOneRef(); bool isShared() const;private: int m_refCounter;};#endif // REFCOUNTER_H/**************************************************author:周翔*e-mail:604487178@qq.com*blog:http://blog.csdn.net/zhx6044***************************************************/#include "refcounter.h"RefCounter::RefCounter():m_refCounter(1){}RefCounter::~RefCounter(){}void RefCounter::plusOneRef(){ ++m_refCounter;}void RefCounter::minusOneRef(){ --m_refCounter;}bool RefCounter::isShared() const{ return m_refCounter > 1;}
/**************************************************author:周翔*e-mail:604487178@qq.com*blog:http://blog.csdn.net/zhx6044***************************************************/#ifndef OBJECT_H#define OBJECT_H#include#include "refcounter.h"class Object : public RefCounter{ friend Object operator +(const Object& _v1, const Object& _v2);public: Object(const char* _value); virtual ~Object(); Object(const Object& _v); const char* className() const;private: char *pd;};#endif // OBJECT_H/**************************************************author:周翔*e-mail:604487178@qq.com*blog:http://blog.csdn.net/zhx6044***************************************************/#include "object.h"#include Object::Object(const char *_value){ pd = new char[strlen(_value) + 1]; strcpy(pd, _value);}Object::~Object(){ if (!isShared()) { delete[] pd; }}Object operator +(const Object& _v1, const Object& _v2){ return Object((std::string(_v1.pd) + _v2.pd).data());}Object::Object(const Object &_v){ pd = new char[strlen(_v.pd) + 1]; strcpy(pd,_v.pd);}const char* Object::className() const{ return pd;}
一个实现引用判断的外裹类模板,封装了逻辑
/**************************************************author:周翔*e-mail:604487178@qq.com*blog:http://blog.csdn.net/zhx6044***************************************************/#ifndef REFCOUNTERWAPPER_H#define REFCOUNTERWAPPER_H#includetemplate class RefCounterWapper{public: RefCounterWapper(T *p); ~RefCounterWapper(); RefCounterWapper(const T& _v); RefCounterWapper(const RefCounterWapper &_v); RefCounterWapper& operator =(const RefCounterWapper& _v); const T* operator ->() const; const T& operator *() const; T* operator ->(); T& operator *();private: T *pd;};template RefCounterWapper ::RefCounterWapper(T *p):pd(p){}template RefCounterWapper ::~RefCounterWapper(){ if (!pd->isShared()) { delete pd; } else { pd->minusOneRef(); }}template RefCounterWapper ::RefCounterWapper(const T &_v){ pd = new T(_v);}template RefCounterWapper ::RefCounterWapper(const RefCounterWapper &_v){ pd = _v.pd; pd->plusOneRef();}template RefCounterWapper & RefCounterWapper ::operator =(const RefCounterWapper& _v){ if (this == &_v) return *this; pd->minusOneRef(); if (!pd->isShared()) { delete pd; } pd = _v.pd; pd->plusOneRef(); return *this;}template const T* RefCounterWapper ::operator ->() const{ return pd;}template const T& RefCounterWapper ::operator *() const{ return *pd;}template T* RefCounterWapper ::operator ->(){ return pd;}template T& RefCounterWapper ::operator *(){ return *pd;}#endif // REFCOUNTERWAPPER_H
供外部使用的具有计数功能的类
/**************************************************author:周翔*e-mail:604487178@qq.com*blog:http://blog.csdn.net/zhx6044***************************************************/#ifndef REFCOUNTEROBJECT_H#define REFCOUNTEROBJECT_H#include "refcounterwapper.h"#include "object.h"class RefCounterObject{ friend RefCounterObject operator +(const RefCounterObject& _v1, const RefCounterObject& _v2);public: RefCounterObject(const char* _v = "Object"); virtual ~RefCounterObject(); const char* className() const;private: RefCounterObject(const Object& _v); RefCounterWapper测试代码
#include#include "refcounterobject.h"using namespace std;int main(){ RefCounterObject v("zhou love cc"); cout << v.className() << endl; RefCounterObject v2 = v; cout << v2.className() << endl; RefCounterObject v3(v2); cout << v3.className() << endl; RefCounterObject v4; cout << v4.className() << endl; v4 = v3; cout << v4.className() << endl; RefCounterObject v5 = v4 + v2; cout << v5.className() << endl;}
5个对象共享了2个Object,它们保存的字符串的值,分别位zhou love cc和zhou love cczhou love cc。
用Valgrind分析了内存,没有内存泄漏
分析Object的析构函数被调用几次
5个对象有两个Object对象,调用析构2次,
还有各一次是
RefCounterObject v4; cout << v4.className() << endl; v4 = v3;//析构v4开始的Object cout << v4.className() << endl; RefCounterObject v5 = v4 + v2;//+操作底层产生一个局部的Object cout << v5.className() << endl;
共享的是RefCounterWapper中pd这个指针指向的对象。
这几个类的关系如图