【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;
}

引用计数是使用指针来管理,可以在多个智能指针间共享一个引用计数。同时加减操作必须都是原子操作,保证线程安全

posted @ 2025-05-01 17:03  丘狸尾  阅读(20)  评论(0)    收藏  举报