66m66成长模式视频威九国际一

核心内容摘要

极尽视听之娱:揭秘久草在线观看视频免费高清资源的终极魅力
噜噜社app官方版:开启你的社交新次元,精彩人生触手可及

极夜寒意:护士办公室那场“不可说”的躁动,真相令人心悸

博主介绍程序喵大人35 - 资深C/C/Rust/Android/iOS客户端开发10年大厂工作经验嵌入式/人工智能/自动驾驶/音视频/游戏开发入门级选手《C20高级编程》《C23高级编程》等多本书籍著译者更多原创精品文章首发gzh见文末记得订阅专栏以防走丢C基础系列专栏C语言基础系列专栏C大佬养成攻略专栏C训练营个人网站C 内存管理的噩梦始于 new/delete 的手动配对止于智能指针的自动化革新。

从 RAII资源获取即初始化的核心理念到 unique_ptr 的独占所有权再到 shared_ptr 的引用计数共享机制智能指针体系不仅解决了内存泄漏和悬空指针的顽疾更通过类型系统明确了资源所有权语义。

本文将深入剖析智能指针的

实现原理手写核心代码助你彻底掌握这一现代 C 基石技术。

RAII资源管理的哲学基石RAIIResource Acquisition Is Initialization资源获取即初始化是 C 最重要的设计理念之一。

其核心思想简单而强大资源的生命周期与对象的生命周期绑定。

在对象构造时获取资源在对象析构时自动释放资源利用 C 栈对象的自动析构机制确保资源正确清理。

classFileHandler{public:FileHandler(conststd::stringpath){fileHandlefopen(path.c_str(),r);// 构造即获取资源}~FileHandler(){if(fileHandle)fclose(fileHandle);// 析构必释放资源}private:FILE*fileHandle;};voidprocessFile(){FileHandlerfile(data.txt);// 自动打开// 使用文件...}// 离开作用域自动关闭即使发生异常RAII 的三大核心特性自动释放告别手动 delete / close异常安全即使发生异常也能正确回收资源禁止拷贝、支持移动资源只能有唯一所有者。

这种设计让资源管理变得可预测、可维护是智能指针诞生的思想基础。

unique_ptr独占所有权的轻量级守护者unique_ptr 体现了独占所有权的清晰语义。

在任何时候只有一个 unique_ptr 可以指向一个给定的对象。

它通过禁止拷贝构造函数和拷贝赋值运算符只提供移动构造函数和移动赋值运算符来实现所有权的唯一性。

手写 unique_ptr 的核心实现templatetypenameTclassMyUniquePtr{private:T*ptr_;public:MyUniquePtr():ptr_(nullptr){}explicitMyUniquePtr(T*ptr):ptr_(ptr){}MyUniquePtr(constMyUniquePtr)delete;MyUniquePtroperator(constMyUniquePtr)delete;MyUniquePtr(MyUniquePtrother)noexcept:ptr_(other.ptr_){other.ptr_nullptr;}MyUniquePtroperator(MyUniquePtrother)noexcept{if(this!other){deleteptr_;ptr_other.ptr_;other.ptr_nullptr;}return*this;}~MyUniquePtr(){deleteptr_;}Toperator*()const{return*ptr_;}T*operator-()const{returnptr_;}T*get()const{returnptr_;}T*release(){T*tempptr_;ptr_nullptr;returntemp;}voidreset(T*ptrnullptr){deleteptr_;ptr_ptr;}explicitoperatorbool()const{returnptr_!nullptr;}};unique_ptr 的核心设计原则零开销抽象性能几乎等同于裸指针异常安全所有权转移过程不抛异常类型安全在编译期防止错误使用。

这也是为什么在现代 C 中unique_ptr 是默认首选的智能指针。

shared_ptr引用计数的共享所有权模型shared_ptr 允许多个指针共享同一个对象通过引用计数机制管理对象生命周期。

当最后一个 shared_ptr 被销毁时对象才会被删除。

其核心是控制块Control Block的设计。

引用计数控制块的内存布局控制块是一个堆上的独立内存区域通常包含以下内容强引用计数use_count弱引用计数weak_count指向被管理对象的指针删除器deletertemplatetypenameTclassControlBlock{public:std::atomicsize_tuse_count{1};std::atomicsize_tweak_count{0};T*ptr{nullptr};std::functionvoid(T*)deleter;ControlBlock(T*p,conststd::functionvoid(T*)del):ptr(p),deleter(del?del:[](T*p){deletep;}){}};手写 shared_ptr 的核心实现templatetypenameTclassMySharedPtr{private:T*ptr_;ControlBlockT*ctrl_block_;voidincrement_ref(){if(ctrl_block_){ctrl_block_-use_count.fetch_add(1,std::memory_order_relaxed);}}voiddecrement_ref(){if(ctrl_block_){if(ctrl_block_-use_count.fetch_sub(1,std::memory_order_acq_rel)

{ctrl_block_-deleter(ctrl_block_-ptr);ctrl_block_-ptrnullptr;if(ctrl_block_-weak_count.load(std::memory_order_acquire)

{deletectrl_block_;}}}}public:MySharedPtr():ptr_(nullptr),ctrl_block_(nullptr){}explicitMySharedPtr(T*ptr):ptr_(ptr),ctrl_block_(newControlBlockT(ptr,nullptr)){}templatetypenameDeleterMySharedPtr(T*ptr,Deleter del):ptr_(ptr),ctrl_block_(newControlBlockT(ptr,del)){}MySharedPtr(constMySharedPtrother):ptr_(other.ptr_),ctrl_block_(other.ctrl_block_){increment_ref();}MySharedPtroperator(constMySharedPtrother){if(this!other){decrement_ref();ptr_other.ptr_;ctrl_block_other.ctrl_block_;increment_ref();}return*this;}MySharedPtr(MySharedPtrother)noexcept:ptr_(other.ptr_),ctrl_block_(other.ctrl_block_){other.ptr_nullptr;other.ctrl_block_nullptr;}~MySharedPtr(){decrement_ref();}Toperator*()const{return*ptr_;}T*operator-()const{returnptr_;}size_tuse_count()const{returnctrl_block_?ctrl_block_-use_count.load(std::memory_order_relaxed):0;}T*get()const{returnptr_;}voidreset(T*ptrnullptr){decrement_ref();if(ptr){ptr_ptr;ctrl_block_newControlBlockT(ptr,nullptr);}else{ptr_nullptr;ctrl_block_nullptr;}}};

引用计数的线程安全性考量shared_ptr 的引用计数在多线程环境下必须是线程安全的标准库通过原子操作来保证这一点。

关键实现细节包括使用 fetch_add / fetch_sub 操作引用计数增加引用时使用 memory_order_relaxed减少引用并可能释放资源时使用 memory_order_acq_relctrl_block_-use_count.fetch_add(1,std::memory_order_relaxed);if(ctrl_block_-use_count.fetch_sub(1,std::memory_order_acq_rel)

{// 释放资源}相比互斥锁原子操作的性能开销要小得多是 shared_ptr 设计中的关键优化点。

循环引用问题的产生与解决当多个对象通过 shared_ptr 相互持有对方时会形成循环引用导致引用计数永远无法归零从而引发内存泄漏。

典型的循环引用场景classB;classA{public:std::shared_ptrBb_ptr;};classB{public:std::shared_ptrAa_ptr;};voidcircularReference(){autoastd::make_sharedA();autobstd::make_sharedB();a-b_ptrb;b-a_ptra;}使用 weak_ptr 打破循环weak_ptr 不增加强引用计数只作为观察者存在。

classB;classA{public:std::shared_ptrBb_ptr;};classB{public:std::weak_ptrAa_ptr;};voidfixedCircularReference(){autoastd::make_sharedA();autobstd::make_sharedB();a-b_ptrb;b-a_ptra;if(autoa_lockedb-a_ptr.lock()){// 对象仍然存在可以安全访问}}

unique_ptr 与 shared_ptr 的核心差异对比维度unique_ptrshared_ptr所有权模型独占所有权共享所有权拷贝语义禁止拷贝仅支持移动支持拷贝内存开销单指针大小指针 控制块运行时开销几乎为零引用计数原子操作线程安全仅对象本身引用计数线程安全适用场景明确唯一所有者多对象共享资源选择原则默认使用 unique_ptr确实需要共享时再使用 shared_ptr出现双向引用时引入 weak_ptr优先使用 make_unique / make_shared 以减少内存分配次数。

结语智能指针是现代 C 内存管理的核心工具。

RAII 提供了思想基础unique_ptr 定义了清晰的独占所有权语义shared_ptr 则通过引用计数实现了安全的共享模型而 weak_ptr 负责解决循环引用这一经典难题。

真正理解并掌握这些智能指针的

实现原理才能在工程实践中写出健壮、高性能、可维护的 C 代码。

码字不易欢迎大家点赞关注评论谢谢

星空无痕mv免费观看完整版高清-星空无痕mv免费观看完整版高清应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123