在看More Effective C++時就有引用計數,如今本身實現了下。ios
完成計數的基類app
/************************************************ * *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。this
用Valgrind分析了內存,沒有內存泄漏spa
分析Object的析構函數被調用幾回.net
5個對象有兩個Object對象,調用析構2次,指針
還有各一次是code
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這個指針指向的對象。對象
這幾個類的關係如圖