c++简略实现共享智能指针Shared_Ptr<T>

重点:

1.引用计数在堆上(原本应为原子变量)

2.引用计数增加减少需要加锁保证线程安全。

3.内部实现Release函数用于释放资源

4.未实现,增加自定义删除器可以将Release修改为模板函数,传入可调用参数。对于shared_ptr,删除器应当作为构造函数参数传入。故而成员函数需要有std::function对象。

#ifndef SHARED_PTR_SHARED_PTR_H
#define SHARED_PTR_SHARED_PTR_H
#include <mutex>

template<typename T>
class Shared_ptr{
public:
    Shared_ptr(T * row) :
    _row_ptr(row),
    _ref_count(new int(1)),
    _ref_mux(new std::mutex)
    {}

    ~Shared_ptr(){ release(); }
    //拷贝构造
    Shared_ptr(const Shared_ptr<T> &sp) :
    _row_ptr(sp._row_ptr),
    _ref_count(sp._ref_count),
    _ref_mux(sp._ref_mux)
    { add_ref(); }
    //拷贝赋值
    Shared_ptr<T>& operator=(const Shared_ptr<T> &sp){
        if (this->_row_ptr != sp._row_ptr){
            release();  //释放管理的旧资源
            _row_ptr = sp._row_ptr;
            _ref_count = sp._ref_count;
            _ref_mux = sp._ref_mux;
            add_ref();
        }
        return *this;
    }

public:
    int& use_count(){ return *_ref_count; }

    T& operator*(){ return *_row_ptr; }

    T* operator->(){ return _row_ptr; }

    T* get(){ return _row_ptr; };

    void reset(T *sp){
        if (this->_row_ptr != sp){
            release();  //释放旧资源,减少引动计数
            _row_ptr = sp;
            _ref_count = new int(1);
            _ref_mux = new std::mutex;
        } else
            add_ref();
    }

private:
    T *_row_ptr;
    int *_ref_count;
    std::mutex *_ref_mux;
    //减少引用计数或释放内存
    void release(){
        std::unique_lock<std::mutex> lock(*_ref_mux);
        if (--(*_ref_count) == 0){
            delete _row_ptr;
            delete _ref_count;
            _row_ptr = nullptr; //避免悬空指针
            _ref_count = nullptr;
        }
    }
    //保证线程安全的前提下加锁增加引用计数
    void add_ref(){
        std::unique_lock<std::mutex> lock(*_ref_mux);
        ++(*_ref_count);
    }
};

#endif //SHARED_PTR_SHARED_PTR_H

测试程序:

#include <iostream>
#include <string>
#include "Shared_ptr.h"

int main() {
    Shared_ptr<std::string> ptr1(new std::string("hello"));
    Shared_ptr<std::string> ptr2(ptr1);
    std::cout << "ptr2 use_count = " << ptr2.use_count() << "ptr1 use_count = " << ptr1.use_count() << std::endl;

    Shared_ptr<std::string> ptr3 = ptr2;
    std::cout << "ptr3 use_count = " << ptr3.use_count() << std::endl;

    std::cout << *ptr2 << std::endl;
    auto str = new std::string("ni hao");
    ptr2.reset(str);
    std::cout << *ptr2 <<" ptr2 usecount = " << ptr2.use_count() << std::endl;
    std::cout << ptr1.use_count() << std::endl;

    return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值