智能指针——shared_ptr的原理及仿写

shared_ptr的原理及仿写

在这里插入图片描述

  • 共享指针允许多个指针指向同一份数据,因为它使用了引用计数,每多一个指针指向这个数据,引用技术加一,每销毁一个指针,引用技术减一,如果引用计数为0,则delete这个数据。
  • 但是共享指针也不能将同一个裸指针赋值给多个智能指针,因为这样会是两个独立的共享指针,它们会分别计数,也就是意味着到时候它们会重复释放。
  • 第一个没有计数器设计的版本:
template<typename T>
class MyShared_ptr {
   
   
private:
    //内部指针
    T* m_ptr;
    //计数器
    long* m_count;
public:
    //以裸指针构造共享指针,默认为nullptr
    //禁止隐式构造
    explicit MyShared_ptr(T* ptr = nullptr) : m_ptr(ptr) {
   
   
        //计数器初始化为1
        m_count = new long(1);
    }
    //以MyUnique_ptr右值构造共享指针
    MyShared_ptr(MyUnique_ptr<T>&& src) {
   
   
        //销毁独占指针,取出裸指针
        m_ptr = src.release();
        //计数器初始化为1
        m_count = new long(1);
    }
    //拷贝构造函数
    MyShared_ptr(const MyShared_ptr& src) {
   
   
        m_ptr = src.m_ptr;
        //拷贝计数器指针
        m_count = src.m_count;
        //计数器加一
        (*m_count)++;
    }
    //拷贝赋值
    MyShared_ptr& operator=(const MyShared_ptr& src) {
   
   
        if (&src == this) return *this;
        //如果自身不为空,先调用析构函数
        if (m_ptr != nullptr) {
   
   
            this->~MyShared_ptr();
        }
        m_ptr = src.m_ptr;
        m_count = src.m_count;
        (*m_count)++;
        return *this;
    }
    //以MyUnique_ptr右值 拷贝赋值
    MyShared_ptr& operator=(const MyUnique_ptr<T>&& src) {
   
   
        if (m_ptr != nullptr) {
   
   
            this->~MyShared_ptr();
        }
        //销毁独占指针,取出裸指针
        m_ptr = src.release();
        m_count = new long(1);
        return *this
### C++ 智能指针 `shared_ptr` 和 `unique_ptr` 的使用方法与区别 #### 使用方法 对于 `std::shared_ptr<T>`,这是一种共享所有权的智能指针。多个 `shared_ptr` 实例可以共同拥有同一个对象,并自动处理资源回收工作。创建时可以直接通过 `make_shared()` 函数来实例化: ```cpp auto ptr1 = std::make_shared<int>(42); ``` 如果需要手动传递原始指针,则应确保正确初始化并考虑是否涉及数组类型的特殊处理[^1]。 而 `std::unique_ptr<T>` 则表示独占性的所有权模型,意味着同一时间只有一个 `unique_ptr` 可以持有某个特定对象的所有权。其构造函数通常接受裸指针作为参数,但不允许复制操作;不过支持移动语义: ```cpp // 创建 unique_ptr 并分配内存给它管理 std::unique_ptr<Person> uptr(new Person()); // 或者更推荐的方式是利用 make_unique (C++14及以上版本) auto uptr2 = std::make_unique<Person>(); ``` 需要注意的是,当 `unique_ptr` 管理的对象不再被任何其他实体引用时,析构函数会负责清理关联的数据结构[^4]。 #### 主要差异 - **所有权模式**: `shared_ptr` 支持多线程环境下的资源共享机制,允许多个指针同时指向相同的动态分配对象;相反地,`unique_ptr` 强调单一所有者的概念,即每次只能有一个这样的指针掌控着某一块堆上开辟的空间。 - **性能开销**: 由于实现了引用计数功能,因此每当有新的 `shared_ptr` 加入到现有对象链表里头或是离开的时候都需要更新内部状态变量,这无疑增加了额外的时间成本以及空间消耗。相比之下,`unique_ptr` 因为不涉及到复杂的跟踪逻辑所以效率更高一些[^2]。 - **可移植性和灵活性**: 虽然两者都能很好地完成各自的任务,但在某些场景下可能更适合选用其中一种类型。比如当我们希望实现 RAII(Resource Acquisition Is Initialization)原则并且不需要跨作用域分享数据的情况下,那么显然应该优先考虑采用 `unique_ptr` 来简化设计思路[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值