C++ 中 shared_ptr 和 unique_ptr 是 C++11 之后被广泛使用的两个智能指针,但是其实他们在使用上还是有一些“秘密”的,我根据平时遇到的两个问题,总结记录一些知识。...在 unique_ptr 内部会保存类型为 T* 和 Deleter 的成员 ,分别表示保存的裸指针和删除器。...继续深挖一下,这个问题会出现在 shared_ptr 吗?答案是不会。这又引入了另一个问题,shared_ptr 和 unique_ptr 的封装有什么不同?...unique_ptr 相当于在编译时绑定了删除器。shared_ptr 保存的是一个控制块的指针。控制块包含的就是一个引用计数和一个原来对象的裸指针。...虽然只是一个小小的知识点,但是也帮助我深入理解了 shared_ptr 和 unique_ptr 在设计上的区别,对于不同使用场景下选择不同智能指针的体会也更加深刻。
在 C++ 中,std::shared_ptr 和 std::unique_ptr 是两种不同的智能指针,它们有不同的所有权语义,不能直接互换,但在特定条件下可以相互转换: 1. unique_ptr...→ shared_ptr (✅ 安全) // unique_ptr 可以转换为 shared_ptr(移动语义) std::unique_ptr unique = std::make_unique...(); // 以下转换是无效的!...会编译错误 std::unique_ptr unique = shared; // 错误:没有转换函数 3....转换工具函数(C++17+): // unique_ptr → shared_ptr template std::shared_ptr make_shared_from_unique
C++的智能指针是一种特殊的指针类型,它能够自动管理内存资源,避免常见的内存泄漏和多次释放等问题。C++11引入了三种主要的智能指针:unique_ptr、shared_ptr和weak_ptr。...不可拷贝:unique_ptr是不可拷贝的,即不能进行复制构造和赋值操作。这是为了确保独占所有权的特性,防止多个指针同时管理同一个对象的内存。...支持移动语义:unique_ptr支持移动构造和移动赋值操作,可以将所有权转移给新的unique_ptr,而无需进行内存拷贝。...指针语义:shared_ptr的使用方式与原始指针相似,可以通过指针操作符(->)和解引用操作符(*)来访问所指向对象的成员。 可拷贝:shared_ptr是可拷贝的,即可以进行复制构造和赋值操作。...弱引用指针和shared_ptr不同,它不会增加引用计数,只是对所指向对象进行观察,并不拥有对象的所有权。
在博文https://blog.csdn.net/qq_27717921/article/details/82940519已经介绍了unique_ptr和shared_ptr的使用,但是这两类的智能指针是如何做到管理指针的呢...的拷贝和赋值操作,更新use_count的相关源码 auto q(p) //调用拷贝构造函数 auto q = p //调用 = 操作符重载 这两句代码涉及到shared_ptr的拷贝构造函数...除了释放p,还要释放use_c, 并将use_c和p 等于nullptr。 和unique_ptr不同, release操作只在析构函数中调用,所以是私有函数。 4....的头文件,拷贝构造函数和=操作符重载函数是delete.这也就说明unique_ptr中不能进行直接拷贝和赋值操作。...函数 ~UniquePointer() { deleter(p); } 和shared_ptr的析构函数不同,unique_ptr的析构函数更简单, 只需要调用类型T的析构函数,如果是自定义类型需要重写
在现代 C + + 编程中,标准库包含智能指针,智能指针可处理对其拥有的内存的分配和删除,这些指针用于帮助确保程序不会出现内存和资源泄漏,并具有异常安全。...unique_ptr,只可以被移动给另一个unique_ptr。...unique_ptr 没有拷贝构造函数,因此不能用于赋值。该指针最常用的情况是单例模式和编译防火墙的封装。...// 演示创建 unique_ptr unique_ptr u_brain = make_unique(); u_brain->HelloWorld(); // 移动 unique_ptr...和 unique 不同的是,它允许自身对象(shared_ptr)被复制,复制出来的 shared_ptr 所托管的指针都指向同一块内存空间。
独占所有权 • std::shared_ptr:共享所有权,通过引用计数管理生命周期 我们从原理、性能和应用场景三个维度来解析。...内部结构 shared_ptr 核心在于 引用计数 和 控制块(control block)。...shared_ptr ├── T* ptr // 实际对象指针 └── ControlBlock* cb // 引用计数和删除器 控制块结构示例: struct ControlBlock...• 两个 shared_ptr 互相引用会造成引用计数不为 0 • 需要 weak_ptr 解决 四、性能分析 特性 unique_ptr shared_ptr 内存占用 小(指针+删除器) 控制块额外开销...unique_ptr,必须共享就用 shared_ptr,控制引用计数就是控制你的性能。”
智能指针利用c++ RAII的特性和模板化编程,本质上是一个包装类,使用起来像普通指针一样方便。当最后一个引用动态对象的智能指针离开作用域或不在引用动态对象后对其进行清理。...--- 智能指针简单实现 这里为了图省事只实现了构造函数、析构函数和基本的运算符,仅供参考。...(std::nullptr_t) {} explicit unique_ptr(T* t) { // 单参构造函数通过explicit禁止隐式转换 _p = t; }...智能指针构造函数利用explicit声明来禁止隐式转换,主要考虑到一些无法确定转换类型的场景。...考虑一种情况:如果一个函数同时出现了unique_ptr和unique_ptr的重载,并且尝试通过隐式转换调用,那么编译器无法推测应该转换为哪种类型。
智能指针是C++中用于自动管理内存的工具,它们通过模拟拥有所有权的对象来防止内存泄漏,其中unique_ptr和shared_ptr是最常用的两种类型。...它通过引用计数来追踪有多少个shared_ptr指向同一资源,当最后一个指向该资源的shared_ptr销毁时,资源被释放。这使得shared_ptr非常适合于复杂数据结构的共享和跨组件传递。...忽略裸指针转换从原始指针到智能指针的转换需谨慎,特别是当原始指针已被其他地方管理时,直接构造智能指针可能会导致重复释放资源。...明智地转换裸指针在将裸指针转换为智能指针之前,确保该指针未被其他智能指针管理。使用make_shared来创建shared_ptr,以减少潜在的内存分配次数和提高效率。...和shared_ptr是C++智能指针家族中的两大支柱,它们各自适用于不同的场景。
最后,一个circle* 是可以隐式转换成 shape*的,但上面的 unique_ptr 却无法自动转换成 unique_ptr。...当最后一个指向对象(和共享计数)的shared_ptr析构时,它需要删除对象和共享计数。...unique_ptr处实现了子类向基类的转换,但是却没有实现基类向子类的转换,例如::unique_ptr转unique_ptr。...cout << "use count of dptr3_1 is now " << dptr3_1.use_count() << endl; // 2 dynamic_cast主要用于类层次间的上行转换和下行转换...在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
下面我们介绍两个常用的智能指针std::shared_ptr和std::weak_ptr。...在TestB析构函数中,调用std::shared_ptr tmp = m_TestA_Ptr.lock(),把std::weak_ptr类型转换成std::shared_ptr类型,然后对TestA对象进行调用...与sp指向相同对象的weak_ptr, T必须能转换为sp指向的类型 w = p; //p可以是shared_ptr或者weak_ptr,赋值后w和p共享对象 w.reset(); //weak_ptr...智能指针小结 可以看出,智能指针其实是std::shared_ptr和std::unique_ptr, std::shared_ptr可以有多个引用对象,但不能互相引用,而std::unique_ptr...只能有一个引用,不能赋值或者拷贝,但可以移动赋值和移动拷贝,std::weak_ptr实际上是对std::shared_ptr的补充,它并不能对对象进行具体的操作。
unique_ptr 和 shared_ptr 支持自定义删除器,即在构造时传入一个可调用对象(函数、lambda、仿函数),来指定资源释放方式。...例如 new[] 需要 delete[] 释放,因此 unique_ptr 和 shared_ptr 也特化了数组版本。...智能指针的 bool 转换 shared_ptr 和 unique_ptr 都支持 operator bool,用于检查智能指针是否为空: std::unique_ptr up; if...防止隐式转换 shared_ptr 和 unique_ptr 的构造函数都使用 explicit 修饰,防止普通指针隐式转换为智能指针: void func(std::unique_ptrunique_ptr(推荐):独占所有权,不支持拷贝,支持移动,适用于不需要共享资源的情况。 shared_ptr(推荐):共享所有权,支持拷贝和移动,底层使用引用计数。
unique_ptr和shared_ptr的构造函数都得使用explicit修饰,防止一般对象发生隐式转换转换成智能指针对象,这也是创建智能指针对象必须显式初始化的原因。...unique_ptr和shared_ptr都支持了operator bool的类型转换,如果智能指针对象没有管理资源就返回false,否则返回true。...由于new[]经常使用,为了方便,所以unique_ptr和shared_ptr都特化了一份[]版本,使用时unique_ptr up1(new Date[5])这样就能够在析构时调用delete...移动的场景使用unique_ptr就好,拷贝的场景使用shared_ptr。 auto_ptr和unique_ptr是独占所有权,不会像shared_ptr一样出现循环引用的问题。...unique_ptr和shared_ptr传递删除器语法的差异:前者传递类型(模板参数),后者传递一个可调用对象。
“智能”指的是使用者不需要关注什么时候是否需要删除这块new出来的内存,内存管理由指针内部自动删除 1.1 范畴 C++11智能指针的范畴包括 类型unique_ptr, shared_ptr和weak_ptr...\n"; } 2.1.4类型转换 使用c++11提供的 static_pointer_cast、const_pointer_case和dynamic_pointer_cast进行基类->派生类的类型转换...; std::shared_ptr dp2; dp2 = std::static_pointer_cast(bp1); // 类型转换...2.3 unique_ptr unique_ptr像是shared_ptr的对立面,因为unique_ptr只运行自身的计数是1或者0,但是因为无需维护引用计数增减,所以他的内部可以设计地更简单,开销更小...的move和reassign std::unique_ptr createTest() { std::unique_ptr localPtr(new Test); return
RAII 的应用场景 内存管理:例如,unique_ptr 和 shared_ptr 是 C++ 中的智能指针,它们的实现就是基于 RAII 模式,自动管理内存资源。...C++标准库中的智能指针都在 这个头文件下,智能指针主要有 auto_ptr、unique_ptr、shared_ptr 和 weak_ptr 等。...template class unique_ptr { public: //防止隐式类型转换 explicit unique_ptr(T* ptr) :_ptr(ptr) {...Date* ptr = new Date; //hz::unique_ptr up1 = ptr; 这种写法编译会出错,explicit不允许隐式类型转换,本质是构造+拷贝 unique_ptr...通过 weak_ptr 无法直接访问对象,需要调用 lock() 方法将其转换为 shared_ptr。
std::unique_ptr支持所有权的转移,可以通过move将一个std::unique_ptr实例的所有权转移到另一个实例。这种所有权转移可以通过移动构造函数和移动赋值运算符来实现。...用于将 std::unique_ptr 对象转换为布尔值。...每当新的shared_ptr添加、超出范围或重置时增加和减少引用计数,当引用计数达到零时,控制块将删除内存资源和自身。...operator bool() 的成员函数, 用于将 std::unique_ptr 对象转换为布尔值。...如果想要使用原生指针的方法,需要将其先转换为一个std::shared_ptr。 weak_ptr可以通过一个shared_ptr创建。
智能指针 智能指针是一种在C++中用于管理动态分配内存的工具,它们提供了更安全和方便的方式来管理内存资源,以避免内存泄漏和资源管理错误。...std::weak_ptr 不能直接访问所管理的内存,需要将其转换为 std::shared_ptr 才能访问内存。... weak = shared; std::shared_ptr sharedAgain = weak.lock(); // 将 weak 转换为 shared_ptr 总结: std...简化代码:使用智能指针可以简化代码,因为它们自然地表达了资源的所有权和生命周期。这提高了代码的可读性和可维护性。...共享 std::shared_ptr:sharedInt 和 anotherSharedInt 指向相同的整数对象,它们共享资源。
why:正确释放动态申请的内存 how:smart pointer(#include) shared_ptr unique_ptr weak_ptr shared_ptr:允许多个指针同时指向同一个对象...),其中args只能以()的形式来初始化shared_ptr,因为shared_ptr的构造函数是explict的,不允许T* ptr这种类型隐式转换成share_ptr,错误样例: shared_ptr...同一块内存别释放两次 // 多删 编程的好习惯是:delete之后重置指针=nullptr可以保证指针不会使用已经delete掉的空间 注意事项 不要混用普通指针和智能指针...>p(q) //error,不存在允许拷贝赋值,所以也没有类似shared_ptr类似的函数 // 观察编译器如何诊断unique_ptr出现赋值,拷贝这种错误 #include #...有一个特列: 思考:为什么shared_ptr没有release函数 因为shared_ptr是可共享的,而且每个shared_ptr的副本都可以delete指向的对象,而 unique_ptr
本文将从底层原理到实际应用,全方位拆解智能指针的设计精髓,带你彻底掌握unique_ptr、shared_ptr、weak_ptr的使用技巧,从此和内存问题说再见!下面就让我们正式开始吧!...二、智能指针的 “三驾马车”:unique_ptr、shared_ptr、weak_ptr C++11 标准库提供了三种核心智能指针:unique_ptr、shared_ptr和weak_ptr...2.1.1 unique_ptr 的核心原理 unique_ptr的底层实现非常简洁: 封装一个裸指针(T* ptr); 禁用拷贝构造函数和拷贝赋值运算符(C++11 中通过= delete实现),确保所有权无法被复制...shared_ptr,unique_ptr不支持(因为unique_ptr的所有权独占,转换会破坏安全性)。...// 错误 int* p = new int(10); unique_ptr up(p); shared_ptr sp(p); // 错误:p被up和sp同时管理,会二次释放 使用get
以下是其核心作用和优势:特化只针对方括号1. 自动内存管理unique_ptr 在其生命周期结束时(如离开作用域)会自动释放所管理的对象,避免内存泄漏。...独占所有权unique_ptr 不允许复制(拷贝构造函数和赋值运算符被禁用),确保同一对象只有一个所有者,避免双重释放问题。...unique_ptr和share_ptr都支持删除器问题出在智能指针默认的删除器不匹配动态数组的内存释放逻辑,导致程序崩溃或内存错误默认删除器会调用 delete 而非 delete[]delete 用于释放单个对象...)前面时,它禁止编译器进行隐式类型转换。...没有移动构造函数和移动赋值(可以作为扩展实现)。如果你需要我扩展成完整支持移动语义的 shared_ptr,或写一个简单的使用 demo/main 函数演示使用,也可以告诉我。
up1也会悬空,移动需谨慎 unique_ptr up3(move(up1)); unique_ptr还支持了operator bool的类型转换,如果智能指针对象是一个空对象(没有管理资源...cout << sp3.use_count() << endl; shared_ptr还支持了operator bool的类型转换,如果智能指针对象是一个空对象(没有管理资源),则返回false,否则返回...但是unique_ptr和shared_ptr的构造时提供删除器的格式还不太一样,也是设计上的一个小缺点了。 实际使用中,除了new,new[]也是经常使用的。...所以unique_ptr和shared_ptr都特化了一种支持new[]的版本,使用如shared_ptr sp(new int[10]);这样,就可以管理new[]的资源了。...注意unique_ptr和shared_ptr的构造函数需要使用explicit修饰, 防止普通指针隐式类型转换成为智能指针对象。