博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
引用计数实现
阅读量:6220 次
发布时间:2019-06-21

本文共 5540 字,大约阅读时间需要 18 分钟。

hot3.png

在看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#include 
template
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 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 
#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这个指针指向的对象。

这几个类的关系如图

转载于:https://my.oschina.net/u/854744/blog/418349

你可能感兴趣的文章
《 线性代数及其应用 (原书第4版)》——1.10 经济学、科学和工程中的线性模型...
查看>>
《JUnit实战(第2版)》—第1章1.4节JUnit的设计目标
查看>>
《OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例》一6.2 基本光照效果
查看>>
在Ubuntu中安装XScreenSaver
查看>>
《HTML5 2D游戏编程核心技术》——第3章,第3.9节使用视差产生视深的假象
查看>>
Practical Clojure - 简介
查看>>
深入下Ruby中的String
查看>>
Django 博客开发教程 4 - 让 Django 完成翻译:迁移数据库
查看>>
《Python密码学编程》——2.7 在线跟踪程序
查看>>
雾里看花之 Python Asyncio
查看>>
《树莓派Python编程入门与实战》——3.9 总结
查看>>
Velocity官方指南-使用Velocity
查看>>
jQuery获取数组对象的值
查看>>
从《一九八四》到《窃听风暴》
查看>>
《jQuery、jQuery UI及jQuery Mobile技巧与示例》——9.2 技巧:用单个HTML文件服务多张页面...
查看>>
360 for Linux 与 setuid
查看>>
《驾驭大数据》一3.5 电力行业:智能电网数据的价值
查看>>
《用户至上:用户研究方法与实践(原书第2版)》一2.5 特殊人群
查看>>
《OpenStack云计算实战手册(第2版)》——1.3 配置Ubuntu Cloud Archive
查看>>
《C#多线程编程实战(原书第2版)》——导读
查看>>