referecen count 的核心思维:使用一个计数器来标识当前指针指向的对象被多少类的对象所使用(即记录指针指向对象被引用的次数)
- 构造函数中创建类的新对象时,初始化引用计数为1;
- 拷贝构造函数复制指针,并使相应的引用计数增加1;
- 赋值操作减少左操作数所值对象的引用计数,增加右操作数所指对象的引用计数;
- 析构函数使引用计数减少1,并且当引用计数为1时,释放指针说指向的对象;
使用引用计数实现智能指针的关键是,引用计数应该存在哪里
引用计数应该是某个类对象和其复制对象共享的, 而指针成员恰好有这样的特性, 故可以在类中多声明一个int * 的成员,用来表示引用计数
代码实现:
#include<iostream>
#include<string>
using namespace std;
class Referenced
{
public:
//首先初始化这个类,引用计数置为一,并且将地址赋给p
Referenced(int *pi)
{
refCount = 1;
p = pi;
}
//计数器+1
int ref()
{
return ++refCount;
}
//计数器-1
int unref()
{
return --refCount;
}
//返回引用计数
int count()
{
return refCount;
}
//析构函数:释放内存
Referenced()
{
cout << "delete referenced" << endl;
delete p;
}
private:
int refCount;//计数器:表示有多少个变量引用这块内存
int *p; //实际指针
};
//对指针进行管理的类,有一个Referenced类的指针ptr
//根据指针中的引用计数来判断是否调用delete来删除指针ptr
class Ref_ptr
{
public:
//使用int *指针初始化ptr,必须要放在初始化列表中
Ref_ptr(int *i) :ptr(new Referenced(i))
{
}
//拷贝构造函数,另一个指针变量指向这块区域
Ref_ptr(const Ref_ptr& rhs)
{
ptr = rhs.ptr;//将右操作数的引用计数对象赋值给左操作数
ptr->ref(); //将其引用计数+1
}
//赋值操作,右操作数的引用计数+1,左操作数的引用计数要-1
Ref_ptr& operator=(const Ref_ptr& rhs)
{
//自己给自己赋值直接返回
if (&rhs == this)
{
return *this;
}
//赋值操作符,首先给当前类的引用计数减一
if (ptr->unref() == 0)
{
cout << "delete Ref_ptr " << endl;
delete ptr;
}
//将右操作数的引用计数赋值给当前的对象
ptr = rhs.ptr;
//引用计数加一
ptr->ref();
return *this;
}
//析构函数,引用计数减为0,删除这快内存
~Ref_ptr()
{
if (ptr->unref() == 0)
{
cout << "delete Ref_ptr" << endl;
delete ptr;
}
}
private:
Referenced * ptr;
};
道理我都懂,代码没头绪,这是参考(抄袭)的原博客:https://blog.csdn.net/u012501459/article/details/48229399