0620# 手写部分

#手写shared_ptr

Tree

shared_ptr
├── 构造函数
│   ├── shared_ptr(T* p = nullptr)
│
├── 拷贝构造函数
│   ├── shared_ptr(const shared_ptr<T>& other)
│
├── 赋值操作符
│   ├── shared_ptr<T>& operator=(const shared_ptr<T>& other)
│
├── 析构函数
│   ├── ~shared_ptr()
│
├── 释放资源函数
│   ├── void release()
│
├── 重置函数
│   ├── void reset(T* p = nullptr)
│
├── 获取原始指针函数
│   ├── T* get() const
│
├── 获取引用计数函数
│   ├── int use_count() const
│
├── 解引用操作符
│   ├── T& operator*() const
│
├── 箭头操作符
│   ├── T* operator->() const
│

代码实现

#include <iostream>

template <typename T>
class shared_ptr {
private:
    T* ptr; // 原始指针
    int* ref_count; // 引用计数

public:
    // 构造函数
    explicit shared_ptr(T* p = nullptr) : ptr(p), ref_count(new int(1)) {
        if (ptr == nullptr) {
            *ref_count = 0;
        }
    }

    // 拷贝构造函数
    shared_ptr(const shared_ptr<T>& other) : ptr(other.ptr), ref_count(other.ref_count) {
        if (ptr) {
            ++(*ref_count);
        }
    }

    // 赋值操作符
    shared_ptr<T>& operator=(const shared_ptr<T>& other) {
        if (this != &other) {
            release();
            ptr = other.ptr;
            ref_count = other.ref_count;
            if (ptr) {
                ++(*ref_count);
            }
        }
        return *this;
    }

    // 析构函数
    ~shared_ptr() {
        release();
    }

    // 释放资源
    void release() {
        if (ptr && --(*ref_count) == 0) {
            delete ptr;
            delete ref_count;
        }
    }

    // 重置
    void reset(T* p = nullptr) {
        release();
        ptr = p;
        ref_count = new int(1);
        if (ptr == nullptr) {
            *ref_count = 0;
        }
    }

    // 获取原始指针
    T* get() const {
        return ptr;
    }

    // 获取引用计数
    int use_count() const {
        return *ref_count;
    }

    // 重载解引用操作符
    T& operator*() const {
        return *ptr;
    }

    // 重载箭头操作符
    T* operator->() const {
        return ptr;
    }
};

int main() {
    shared_ptr<int> sp1(new int(10));
    std::cout << "sp1 use_count: " << sp1.use_count() << std::endl;
    {
        shared_ptr<int> sp2 = sp1;
        std::cout << "sp1 use_count after sp2: " << sp1.use_count() << std::endl;
        std::cout << "sp2 use_count: " << sp2.use_count() << std::endl;
    }
    std::cout << "sp1 use_count after sp2 out of scope: " << sp1.use_count() << std::endl;
    return 0;
}

输出

sp1 use_count: 1
sp1 use_count after sp2: 2
sp2 use_count: 2
sp1 use_count after sp2 out of scope: 1

构造函数

explicit shared_ptr(T* p = nullptr) : ptr(p), ref_count(new int(1)) {
    if (ptr == nullptr) {
        *ref_count = 0;
    }
}
  • ptr 初始化为传入的指针 p
  • ref_count 初始化为一个新的整数,并设为1(初始引用计数)。
  • 如果 pnullptr,则将引用计数设为0。

拷贝构造函数

shared_ptr(const shared_ptr<T>& other) : ptr(other.ptr), ref_count(other.ref_count) {
    if (ptr) {
        ++(*ref_count);
    }
}
  • ptrref_count 拷贝自 other
  • 如果 ptr 非空,则增加引用计数。

赋值操作符

shared_ptr<T>& operator=(const shared_ptr<T>& other) {
    if (this != &other) {
        release(); // 释放当前持有的资源
        ptr = other.ptr;
        ref_count = other.ref_count;
        if (ptr) {
            ++(*ref_count);
        }
    }
    return *this;
}
  • 先检查是否自我赋值,如果是则直接返回当前对象。
  • 调用 release() 函数释放当前持有的资源。
  • 拷贝 ptrref_count,并增加引用计数。

析构函数

~shared_ptr() {
    release(); // 释放资源
}
  • 调用 release() 函数释放资源。

释放资源

void release() {
    if (ptr && --(*ref_count) == 0) {
        delete ptr;
        delete ref_count;
    }
}
  • 检查 ptr 是否非空,并减少引用计数。
  • 如果引用计数为0,删除对象和引用计数器。

重置

void reset(T* p = nullptr) {
    release(); // 释放当前持有的资源
    ptr = p;
    ref_count = new int(1);
    if (ptr == nullptr) {
        *ref_count = 0;
    }
}
  • 释放当前持有的资源。
  • ptr 设为新的指针 p,并重新初始化引用计数。

获取原始指针

T* get() const {
    return ptr;
}
  • 返回原始指针 ptr

获取引用计数

int use_count() const {
    return *ref_count;
}
  • 返回引用计数的值。

运算符重载

T& operator*() const {
    return *ptr;
}

T* operator->() const {
    return ptr;
}
  • 提供解引用操作符 * 和箭头操作符 ->,使 shared_ptr 能像普通指针一样使用。

 测试代码

int main() {
    shared_ptr<int> sp1(new int(10));
    std::cout << "sp1 use_count: " << sp1.use_count() << std::endl; // 输出1
    {
        shared_ptr<int> sp2 = sp1; // 拷贝构造
        std::cout << "sp1 use_count after sp2: " << sp1.use_count() << std::endl; // 输出2
        std::cout << "sp2 use_count: " << sp2.use_count() << std::endl; // 输出2
    }
    // sp2 离开作用域,引用计数减1
    std::cout << "sp1 use_count after sp2 out of scope: " << sp1.use_count() << std::endl; // 输出1
    return 0;
}

这个测试代码展示了 shared_ptr 如何管理引用计数。当 sp2 离开作用域时,它的析构函数被调用,引用计数减1,最终 sp1 的引用计数回到1。

P.S.

#手写weak_ptr

#手写vector

#手写string

#手写线程池

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值