【C++】带引用计数的智能指针 仿实现
#include <iostream>
#include <memory>
#include <thread>
using namespace std;
// 利用栈上的对象出作用域自动析构的特征,来做到资源的自动释放
template <typename T>
class RefCnt {
public:
// 构造函数,初始化引用计数为1
RefCnt(T *ptr) : mptr(ptr), mcount(1) {}
// 增加引用计数
void addRef() {
++mcount;
}
// 减少引用计数,若引用计数为0则释放资源
int delRef() {
if (--mcount == 0) {
delete mptr;
mptr = nullptr;
}
return mcount;
}
private:
T *mptr;
int mcount; // atomic_int
};
// 利用栈上的对象出作用域自动析构的特征,来做到资源的自动释放
template <typename T>
class CSmartPtr {
public:
// 构造函数,初始化指针和引用计数
CSmartPtr(T* ptr = nullptr)
: mptr(ptr), mpRefCnt(new RefCnt<T>(ptr)) {}
// 析构函数,减少引用计数,若为0则释放资源
~CSmartPtr() {
if (mpRefCnt && 0 == mpRefCnt->delRef()) {
delete mpRefCnt;
}
}
// 重载 -> 运算符,返回指针
T* operator->() {
return mptr;
}
// 重载 * 运算符,返回引用
T& operator*() {
return *mptr;
}
// 拷贝构造函数,增加引用计数
CSmartPtr(const CSmartPtr<T> &src)
: mptr(src.mptr), mpRefCnt(src.mpRefCnt) {
if (mpRefCnt) {
mpRefCnt->addRef();
}
}
// 赋值运算符重载
CSmartPtr<T>& operator=(const CSmartPtr<T> &src) {
if (this == &src) {
return *this;
}
// 减少当前对象的引用计数
if (mpRefCnt && 0 == mpRefCnt->delRef()) {
delete mpRefCnt;
}
// 复制指针和引用计数
mptr = src.mptr;
mpRefCnt = src.mpRefCnt;
// 增加新引用计数,线程安全
if (mpRefCnt) {
mpRefCnt->addRef();
}
return *this;
}
private:
T* mptr;
RefCnt<T> *mpRefCnt;
};
// main线程
int main() {
CSmartPtr<int> p1(new int);
CSmartPtr<int> p2(p1);
CSmartPtr<int> p3;
p3 = p2;
return 0;
}
引用计数是使用指针来管理,可以在多个智能指针间共享一个引用计数。同时加减操作必须都是原子操作,保证线程安全

浙公网安备 33010602011771号