实现引用计数
- 引言
- 实现
- 集成开发环境
- 项目结构
- 实现代码
- 运行结果
- 注意
引言
C++中经常使用智能指针来管理内存。对于共享指针shared_ptr的原理:每当有一个指针指向这块内存,引用计数的值加一,每当一个指针不再指向这块内存,引用计数的值减一,知道引用计数的值减为0,则释放这块内存。
本文旨在根据其原理实现引用计数(几年前的那一篇有很大的上升空间,哈哈~)。
实现
集成开发环境
visual studio 2019+Debug x86编译平台。
项目结构
直接打开vs2019,创建基于C++的Windows空项目,添加一个主函数类,添加一个引用计数需要的头文件hpp。
实现代码
引用计数的代码实现:
#pragma once
class common_cache {
public:
uint32_t m_count;
void* m_pcache;
common_cache() {
m_count = 0;
m_pcache = NULL;
}
~common_cache() {
m_count = 0;
if (m_pcache) {
delete[] m_pcache;
m_pcache = NULL;
}
}
};
template<typename T>
class ref_count {
public:
ref_count() {
m_pref_ount = new common_cache();
m_pref_ount->m_pcache = new T;
add();
}
~ref_count() {
sub();
}
ref_count(ref_count<T>* t) {
m_pref_ount = t->m_pref_ount;
add();
}
ref_count(ref_count<T>& t) {
m_pref_ount = t.m_pref_ount;
add();
}
ref_count& operator=(ref_count<T>& t) {
sub();
m_pref_ount = t.m_pref_ount;
add();
}
uint32_t add() {
return ++m_pref_ount->m_count;
}
void sub() {
if (m_pref_ount->m_count > 0) {
--m_pref_ount->m_count;
}
if (m_pref_ount->m_count == 0 && m_pref_ount != NULL) {
delete m_pref_ount;
m_pref_ount = NULL;
}
}
uint32_t get_cunt() {
return m_pref_ount->m_count;
}
T* data() {
return (T*)m_pref_ount->m_pcache;
}
public:
common_cache* m_pref_ount;
};
主函数的实现,其中主要是引用计数的使用,或者说是验证。代码如下:
#include <iostream>
#include "Counter.hpp"
using namespace std;
int main(int argc,char *argv[]) {
ref_count<int> a;
int* test = a.data();
*test = 9;
cout << "当前的引用计数 a:" << a.get_cunt() << endl;
ref_count<int> b(a);
cout << "当前的引用计数 b:" << b.get_cunt() <<","<< a.get_cunt() << endl;
ref_count<int> c = b;
cout << "当前的引用计数 c:" << c.get_cunt() << "," << a.get_cunt()<< endl;
{
ref_count<int> d = b;
cout << "当前的引用计数 d :" << d.get_cunt() << "," << a.get_cunt()<< endl;
}
cout << "当前的引用计数 c:" << c.get_cunt() << "," << a.get_cunt()<< endl;
return 0;
}
运行结果
注意
上述引用计数实现时,需要注意的是,对于计数所用的加计数/减计数变量,以及指向共有的内存所用的指针需要作为一个共有的部分,可以被多个不同的智能指针都访问到,且不能直接作为引用计数类的直接数据成员。(注意理解,直接作为类成员,则对于类对象而言,为当前的类对象所拥有,计数时便不能做到引用计数的值被多个类所共用)