手写Shared_ptr

📅 2026/8/2 3:25:54
手写Shared_ptr
shared_ptr是C11引入的智能指针通过引用计数功能实现多个指针共享一个对象的所有权。核心原理每个shared_ptr内部有一个引用计数拷贝时计数加一析构时计数减一计数降为0时自动删除所管理的对象。1.自动内存管理有效避免内存泄漏与野指针。2.共享对象所有权3.可以跨线程共享。#include atomic #include utility #include functional templatetypename T class SharedPtr { private: T* ptr_; std::atomicsize_t* ref_count_; public: // 默认构造 SharedPtr() noexcept : ptr_(nullptr), ref_count_(nullptr) {} // 从原始指针构造 explicit SharedPtr(T* ptr) : ptr_(ptr), ref_count_(nullptr) { if (ptr_) { ref_count_ new std::atomicsize_t(1); } } // 拷贝构造 SharedPtr(const SharedPtr other) noexcept : ptr_(other.ptr_), ref_count_(other.ref_count_) { if (ref_count_) { ref_count_-fetch_add(1, std::memory_order_relaxed); } } // 移动构造 SharedPtr(SharedPtr other) noexcept : ptr_(other.ptr_), ref_count_(other.ref_count_) { other.ptr_ nullptr; other.ref_count_ nullptr; } // 拷贝赋值 SharedPtr operator(const SharedPtr other) noexcept { if (this ! other) { SharedPtr temp(other); swap(temp); } return *this; } // 移动赋值 SharedPtr operator(SharedPtr other) noexcept { if (this ! other) { SharedPtr temp(std::move(other)); swap(temp); } return *this; } // 析构 ~SharedPtr() { release(); } // 交换 void swap(SharedPtr other) noexcept { std::swap(ptr_, other.ptr_); std::swap(ref_count_, other.ref_count_); } // 解引用 T operator*() const noexcept { return *ptr_; } T* operator-() const noexcept { return ptr_; } // 获取原始指针 T* get() const noexcept { return ptr_; } // 引用计数 size_t use_count() const noexcept { return ref_count_ ? ref_count_-load(std::memory_order_relaxed) : 0; } // 是否独占 bool unique() const noexcept { return use_count() 1; } // 重置为空 void reset() noexcept { release(); ptr_ nullptr; ref_count_ nullptr; } // 重置为新指针 void reset(T* ptr) { reset(); if (ptr) { ptr_ ptr; ref_count_ new std::atomicsize_t(1); } } // 布尔转换判断是否非空 explicit operator bool() const noexcept { return ptr_ ! nullptr; } private: void release() noexcept { if (ref_count_) { if (ref_count_-fetch_sub(1, std::memory_order_acq_rel) 1) { delete ptr_; delete ref_count_; } ptr_ nullptr; ref_count_ nullptr; } } };