文档章节

引用计数实现

首席吹牛官
 首席吹牛官
发布于 2015/05/22 12:56
字数 734
阅读 3
收藏 0

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


这几个类的关系如图






© 著作权归作者所有

首席吹牛官
粉丝 9
博文 368
码字总数 191938
作品 0
闵行
程序员
私信 提问
Android上C++对象的自动回收机制分析

1. 背景 C++没有像Java那样的内建的对象自动回收机制,new创建的对象没有delete,会一直存在于内存中。对象已经不再使用,但是如果忘记 delete,会造成内存资源的泄露。在实际开发过程中,分...

阿酷
2011/12/26
1K
0
探寻Objective-C引用计数本质

本文涉及到的CPU架构为arm64,其它架构大同小异。 源码来自苹果开源-runtime。 Objective-C中采用引用计数机制来管理内存,在MRC时代,需要我们手动和,在苹果引入ARC后大部分时间我们不用再...

莫云溪
2018/05/26
0
0
Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析【转】

Android系统的运行时库层代码是用C++来编写的,用C++ 来写代码最容易出错的地方就是指针了,一旦使用不当,轻则造成内存泄漏,重则造成系统崩溃。不过系统为我们提供了智能指针,避免出现上述...

yooooooo
2018/08/20
0
0
Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析

Android系统的运行时库层代码是用C++来编写的,用C++来写代码最容易出错的地方就是指针了,一旦使用不当,轻则造成内存泄漏,重则造成系统崩溃。不过系统为我们提供了智能指针,避免出现上述...

鉴客
2011/10/17
1K
0
objective-c启用ARC时的内存管理

PDF版下载:http://download.csdn.net/detail/cuibo1123/7443125 在objective-c中,内存的引用计数一直是一个让人比较头疼的问题。尤其是当引用计数涉及到arc、blocks等等的时候。似乎ARC的出...

cuibo1123
2014/06/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Giraph源码分析(八)—— 统计每个SuperStep中参与计算的顶点数目

作者|白松 目的:科研中,需要分析在每次迭代过程中参与计算的顶点数目,来进一步优化系统。比如,在SSSP的compute()方法最后一行,都会把当前顶点voteToHalt,即变为InActive状态。所以每次...

数澜科技
今天
4
0
Xss过滤器(Java)

问题 最近旧的系统,遇到Xss安全问题。这个系统采用用的是spring mvc的maven工程。 解决 maven依赖配置 <properties><easapi.version>2.2.0.0</easapi.version></properties><dependenci......

亚林瓜子
今天
10
0
Navicat 快捷键

操作 结果 ctrl+q 打开查询窗口 ctrl+/ 注释sql语句 ctrl+shift +/ 解除注释 ctrl+r 运行查询窗口的sql语句 ctrl+shift+r 只运行选中的sql语句 F6 打开一个mysql命令行窗口 ctrl+l 删除一行 ...

低至一折起
今天
9
0
Set 和 Map

Set 1:基本概念 类数组对象, 内部元素唯一 let set = new Set([1, 2, 3, 2, 1]); console.log(set); // Set(3){ 1, 2, 3 } [...set]; // [1, 2, 3] 接收数组或迭代器对象 ...

凌兮洛
今天
4
0
PyTorch入门笔记一

张量 引入pytorch,生成一个随机的5x3张量 >>> from __future__ import print_function>>> import torch>>> x = torch.rand(5, 3)>>> print(x)tensor([[0.5555, 0.7301, 0.5655],......

仪山湖
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部