在看More Effective C++时就有引用计数,现在自己实现了下。
完成计数的基类
/************************************************
*
*author:周翔
*e-mail:604487178@qq.com
*blog:http://blog.csdn.net/zhx6044
*
*
*************************************************/
#ifndef REFCOUNTER_H
#define REFCOUNTER_H
#include <iostream>
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 <cstring>
#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 <iostream>
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
#include <iostream>
template <typename T>
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 <typename T>
RefCounterWapper<T>::RefCounterWapper(T *p):pd(p)
{
}
template <typename T>
RefCounterWapper<T>::~RefCounterWapper()
{
if (!pd->isShared()) {
delete pd;
} else {
pd->minusOneRef();
}
}
template <typename T>
RefCounterWapper<T>::RefCounterWapper(const T &_v)
{
pd = new T(_v);
}
template <typename T>
RefCounterWapper<T>::RefCounterWapper(const RefCounterWapper &_v)
{
pd = _v.pd;
pd->plusOneRef();
}
template <typename T>
RefCounterWapper<T>& RefCounterWapper<T>::operator =(const RefCounterWapper& _v)
{
if (this == &_v) return *this;
pd->minusOneRef();
if (!pd->isShared()) {
delete pd;
}
pd = _v.pd;
pd->plusOneRef();
return *this;
}
template <typename T>
const T* RefCounterWapper<T>::operator ->() const
{
return pd;
}
template <typename T>
const T& RefCounterWapper<T>::operator *() const
{
return *pd;
}
template <typename T>
T* RefCounterWapper<T>::operator ->()
{
return pd;
}
template <typename T>
T& RefCounterWapper<T>::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<Object> pd;
};
RefCounterObject::RefCounterObject(const char *_v):pd(new Object(_v))
{
}
RefCounterObject::~RefCounterObject()
{
}
RefCounterObject operator +(const RefCounterObject& _v1, const RefCounterObject& _v2)
{
return RefCounterObject((*_v1.pd) + (*_v2.pd));
}
RefCounterObject::RefCounterObject(const Object &_v):pd(_v)
{
}
const char* RefCounterObject::className() const
{
return pd->className();
}
#endif // REFCOUNTEROBJECT_H
测试代码
#include <iostream>
#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这个指针指向的对象。
这几个类的关系如图