shared_ptr智能指针简单实现

shared_ptr是C++标准库中的智能指针,用于实现共享所有权的内存管理。它通过引用计数来跟踪多个智能指针指向同一对象的情况。当引用计数减少到零时,对象会被自动删除。文章展示了shared_ptr的构造、拷贝构造、赋值运算符以及use_count方法的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

shared_ptr 简介:

        shared_ptr 是 C++ 标准库中的一种智能指针,它实现了共享所有权的内存管理,可以让多个智能指针同时管理同一个对象。shared_ptr 通过引用计数的方式来管理内存,即每个 shared_ptr 对象都会维护一个引用计数器,记录有多少个 shared_ptr 对象指向同一个对象。

 shared_ptr.h简单实现智能指针的一些接口,下面是测试结果

#include "shared_ptr.h"
#include <iostream>
using namespace std;
class Ball{
public:
    Ball(){
        cout<<"a ball haved create"<<endl;
    }

    ~Ball(){
        cout<<"a ball haved destroy"<<endl;
    }

    void Bolls(){
        cout << "a ball is fetched"<<endl;
    }
};
int main(){
    //创建一个指向Ball的智能指针对象p1
    shared_ptr<Ball>p1{ new Ball() };
    //Ball对象只有一个智能指针指向,所以应该输出1
    cout << p1.use_count() << endl;

    //创建一个指向Ball的智能指针对象p2
    shared_ptr<Ball>p2(p1);
    //Ball对象有两个智能指针指向,所以应该输出2
    cout <<p1.use_count()<<" " << p2.use_count()<<endl;
    
    return 0;
}

运行结果

a ball haved create
1
2 2
a ball haved destroy

shared_ptr.h实现

我们首先定义两个类私有成员原始指针(ptr_)和引用计数(ref_count_)

private:

    //原始指针
    T* ptr_;            
    
    //引用计数
    size_t* ref_count_; 

类构造函数,如果初始化了ptr,即指向了对象,我们的引用计数初始化为1

测试用例的shared_ptr<Ball>p1{ new Ball() };就调用了下面的构造函数,语句ptr指向Ball对象

    shared_ptr(T* ptr = nullptr) {
        if (ptr) {
            ref_count_ = new size_t(1);
            ptr_ = ptr;
        }
    }

执行第一条语句后指针指向 

 

 拷贝构造函数,语句shared_ptr<Ball>p2(p1);使用的就是拷贝构造函数,将参数p1的东西赋值给p2对象,并让引用计数器加1

    shared_ptr(const shared_ptr<T>& other) {
        ptr_ = other.ptr_;
        ref_count_ = other.ref_count_;
        if (ref_count_) {
            ++(*ref_count_);
        }
    }

 执行语句shared_ptr<Ball>p2(p1)后的指针指向

可以看到每创建一个智能指针对象指向同一个对象时,计数器ref_count_就会加1,这个是shared_ptr的核心。

shared_ptr智能指针对象在离开作用域后就会调用析构函数,--(*ref_count_) == 0 语句判断是否只有自己一个指针指向对象,即引用计数减1后是否为0,如果是,我们就释放掉指针指向的资源,即对象资源。

    ~shared_ptr() {
        if (ref_count_ && --(*ref_count_) == 0) {
            //释放掉指向的资源
            delete ptr_;    
            delete ref_count_;
        }
    }

重载赋值运算符

    shared_ptr<T>& operator=(const shared_ptr<T>& other) {
        if (this != &other) {
            ptr_ = other.ptr_;
            ref_count_ = other.ref_count_;
            if (ref_count_) {
                ++(*ref_count_);
            }
        }
        return *this;
    }

获取计数器

    size_t use_count() const {
        return ref_count_ ? *ref_count_ : 0;
    }

完整代码

#include <cstddef>  
template <typename T>
class shared_ptr{
public:
    //构造函数
    shared_ptr(T* ptr = nullptr) {
        if (ptr) {
            ref_count_ = new size_t(1);
            ptr_ = ptr;
        }
    }

    shared_ptr(const shared_ptr<T>& other) {
        ptr_ = other.ptr_;
        ref_count_ = other.ref_count_;
        if (ref_count_) {
            ++(*ref_count_);
        }
    }

    ~shared_ptr() {
        if (ref_count_ && --(*ref_count_) == 0) {
            delete ptr_;
            delete ref_count_;
        }
    }

    shared_ptr<T>& operator=(const shared_ptr<T>& other) {
        if (this != &other) {
            ptr_ = other.ptr_;
            ref_count_ = other.ref_count_;
            if (ref_count_) {
                ++(*ref_count_);
            }
        }
        return *this;
    }

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

    T* operator->() const {
        return ptr_;
    }

    operator bool() const {
        return ptr_;
    }

    //获取原始指针
    T* get() const{
        return ptr_;
    }
    
    //获取计数器
    size_t use_count() const {
        return ref_count_ ? *ref_count_ : 0;
    }

private:

    //原始指针
    T* ptr_;            
    
    //引用计数
    size_t* ref_count_; 
};

后面就添加一些接口,可以自己实现,如果代码有问题,欢迎提出意见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清酒半生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值