首页
学习
活动
专区
圈层
工具
发布

shared_ptr 和 unique_ptr 深入探秘

C++ 中 shared_ptr 和 unique_ptr 是 C++11 之后被广泛使用的两个智能指针,但是其实他们在使用上还是有一些“秘密”的,我根据平时遇到的两个问题,总结记录一些知识。...在 unique_ptr 内部会保存类型为 T* 和 Deleter 的成员 ,分别表示保存的裸指针和删除器。...继续深挖一下,这个问题会出现在 shared_ptr 吗?答案是不会。这又引入了另一个问题,shared_ptr 和 unique_ptr 的封装有什么不同?...shared_ptr 保存的是一个控制块的指针。控制块包含的就是一个引用计数和一个原来对象的裸指针。控制块中初始化的指针是 nullptr,在运行时为其赋值,也可以通过 reset 修改。...虽然只是一个小小的知识点,但是也帮助我深入理解了 shared_ptr 和 unique_ptr 在设计上的区别,对于不同使用场景下选择不同智能指针的体会也更加深刻。

86610
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    boost 智能指针 shared_ptr

    但只有 shared_ptr 是最接近普通指针的一种智能指针,他具有一些非常良好的特性,比如计数器等等,使用 shared_ptr 可以让我们不用花费精力在内存回收上。...其他的一些指针与 shared_ptr 的区别如下表: 本文主要介绍 shared_ptr 的一些特性,以后如果你使用到 boost 库,那么用到这个智能指针也会是最多的。...1、boost::shared_ptr****实现了计数引用: 它包装了new操作符在堆上分配的动态对象,但它实现了引用计数,可以自由的拷贝和赋值,在任意地方共享它。...例如std::vector IntVec,使用shared_ptr方式为std::vectorshared_ptr > IntptrVec. 4、boost::shared_ptr...::shared_ptr ptr_MyClass(new MyClass()); ptr_obj = ptr_MyClass; ptr_obj->func(); // 智能指针避免普通指针和智能指针混用

    55810

    面试官:为什么大厂拒绝使用shared_ptr(shared_ptr vs intrusive_ptr)?

    原子 strong_ref++ 和 strong_ref-- // ......在多个线程和函数调用中不断传递 ... } 在一个100GB/s带宽、百万IOPS的集群中,假设每个IO请求在生命周期内平均经历10次 shared_ptr的拷贝/析构,那么每秒就会发生 100万...即使使用 make_shared优化,将两次分配合并为一次, 控制块和对象T仍然在内存上是紧邻的同一个内存块。...对象和计数器在一起,常在同一缓存行。 可能缓存不友好。对象和控制块可能分离。 性能 稍高。无额外分配,缓存局部性更好。但原子操作开销仍在。 稍低。有分配开销,可能缓存不友好。 侵入性 是。...必须修改类定义,添加计数器和友元函数。 否。无需修改类即可使用,是非侵入式的。 易用性 复杂。需要手动实现引用计数逻辑,容易出错。 简单。开箱即用,自动化程度高。 适用场景 1.

    22910

    【C++】智能指针:shared_ptr

    一、产生的原因 shared_ptr的产生与unique_ptr类似,都是为了解决raw pointer的new和delete的成对使用,导致的野指针、内存泄漏、重复释放内存等。...Several shared_ptr objects may own the same object. https://en.cppreference.com/w/cpp/memory/shared_ptr...思想是:该类型智能指针在实现上采用的是引用计数机制,即便有一个 shared_ptr 指针放弃了堆内存的“使用权”(引用计数减 1),也不会影响其他指向同一堆内存的 shared_ptr 指针(只有引用计数为...默认构造函数分配的是空指针 constructor with object Foo... 2 // sh2 和sh3指向的都是同一个内存,所以他们的引用计数都是2 2 ~Foo... constructor...= std::make_shared (10); // same as: make_shared是推荐的用法,因为它会一次性将raw pointer和引用计数的内存同时分配好 std

    3.3K20

    js变量提升 和函数提升

    两个最简单的例子理解变量声明提升和函数声明提升 一、变量提升 变量提升即将变量声明提升到它所在作用域的最开始的部分 例1: function fn () { var a ="hello...但是我需要说明的是,变量提升 只是提升变量的声明,并不会把赋值也提升上来 二、函数提升 js中创建函数有两种方式:一种是函数表达式,另外一种是函数声明方式。只有函数声明才存在函数提升!...,整个代码块提升到文件的最开始  console.log(fun1); console.log(fun2); var fun2 = function() {} 总结和注意点 1、变量提升 1...,不会去外层作用域了 3、let和const关键字没有变量提升 2、函数提升 1、如果在同一个作用域中存在多个同名函数声明,后面出现的将会覆盖前面的函数声明 2、函数声明的优先级最高,会被提升至当前作用域最顶端...,然后才是函数表达式和变量按顺序执行

    1.8K41

    C++的智能指针unique_ptr、shared_ptr和weak_ptr

    C++的智能指针是一种特殊的指针类型,它能够自动管理内存资源,避免常见的内存泄漏和多次释放等问题。C++11引入了三种主要的智能指针:unique_ptr、shared_ptr和weak_ptr。...支持移动语义:unique_ptr支持移动构造和移动赋值操作,可以将所有权转移给新的unique_ptr,而无需进行内存拷贝。...指针语义:shared_ptr的使用方式与原始指针相似,可以通过指针操作符(->)和解引用操作符(*)来访问所指向对象的成员。 可拷贝:shared_ptr是可拷贝的,即可以进行复制构造和赋值操作。...弱引用指针和shared_ptr不同,它不会增加引用计数,只是对所指向对象进行观察,并不拥有对象的所有权。...weak_ptr 具有以下特点和用法: 弱引用:因为 weak_ptr 不会增加引用计数,所以当所有 shared_ptr 都释放后,weak_ptr 将自动失效。

    2.4K20

    善用shared_ptr,远离内存泄漏(文末福利)

    shared_ptr允许多个指向同一个对象,当指向对象的最后一个shared_ptr销毁时,该对象也就会自动销毁。因此,善用shared_ptr,能够远离内存泄漏。...拷贝 例如: auto sp2 = make_shared(1024); auto sp1(sp2); 该操作会使得sp1和sp2都指向同一个对象。...关于参数传值的问题,可以参考《传值与传指针》和《令人疑惑的引用和指针》。 reset 调用reset会减少计数: sp.reset() 而如果sp是唯一指向该对象的,则该对象被销毁。...存放于容器中的shared_ptr 如果你的容器中存放的是shared_ptr,而你后面又不再需要它时,记得使用erase删除那些不要的元素,否则由于引用计数一直存在,其对象将始终得不到销毁,除非容器本身被销毁...总结 以上就是shared_ptr基本内容,一般来说,规范使用shared_ptr能很大程度避免内存泄露。注意,shared_ptr提供,*,->操作,不直接提供指针运算和[]。

    2K10

    shared_ptr是线程安全的吗?

    Reading a shared_ptr from two threads // thread A shared_ptr p2(p); // reads p // thread B shared_ptr...结论:多个线程同时读同一个shared_ptr对象是线程安全的, 但是如果是多个线程对同一个shared_ptr对象进行读和写,则需要加锁。 这里举个例子:怎么多线程调度执行顺序的不确定性。 ?...ref_count 对象有多个成员,具体的数据结构如图 1 所示,其中 deleter 和 allocator 是可选的。 ? 图 1:shared_ptr 的数据结构。...步骤1和步骤2的先后顺序跟实现相关(因此步骤 2 里没有画出 y.ptr 的指向), 我见过的都是先1后2。...2:多线程无保护读写 shared_ptr 可能出现的 race condition 考虑一个简单的场景,有 3 个 shared_ptr 对象 x、g、n: shared_ptr

    12.1K31

    深入剖析:boost::intrusive_ptr 与 std::shared_ptr 的性能边界和实现哲学

    1. std::shared_ptr 的开销结构:分离式控制块 std::shared_ptr 的设计哲学是 非侵入式。这意味着它能够管理任何类型的对象 T,无需 T 本身具备引用计数的能力。...删除器(Deleter) 和 分配器(Allocator):可选,用于资源释放。...性能瓶颈分析: 当多个线程同时对同一个 shared_ptr 进行复制或销毁操作时(例如,通过不同的 shared_ptr 实例访问同一个对象),它们都需要修改 控制块 中的引用计数。...结论:intrusive_ptr 的速度优势并非仅仅是“原子操作更快”,而是其侵入式内存布局从根本上提升了缓存局部性,显著降低了多核环境下的缓存一致性同步开销。...哲学意义:通过 ADL 和友元机制,intrusive_ptr 实现了 策略模式 的效果。

    23410

    整形提升和算数转换

    为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整形,这种转换称为整形提升。 我们常见的int实际上是signed int(有符号整形),另一种为unsigned int。...a和b都是8位的,但他们要进行运算,因此我们需要先进行整形提升,然后才能相加。  又因为c也是字符型变量,所以对c也是取最小的8位,然后保存在内存中。...注意:整形提升时,如果是有符号的,高位要补符号位,如果是无符号的,高位直接补0.  例子2: 我们看到,只打印了c。 分析:a和b需要进行整形提升,但是c不需要整数提升。...a和b整数提升后都变成了负数,表达式都为假,所以只打印了c。...例子3:  分析:c只要参与表达式运算,就会发生整形提升,表达式+c和-c都会发生整形提升,sizeof(+c)和sizeof(-c)都是4个字节,而sizeof(c)不发生整形提升,因此为1个字节。

    41110

    【CC++ make_shared和shared_ptr直接初始化有什么区别?】

    std::make_shared 和直接使用 std::shared_ptr 初始化是 C++ 中创建共享智能指针的两种不同方式。它们之间的主要区别在于内存分配、效率、异常安全性和使用上的便利性。...std::make_shared 则将被管理的对象和引用计数块(控制块)一起分配在同一块内存上,这样可以减少内存分配的次数,提高内存使用效率。...std::make_shared 保证了即使构造函数抛出异常,内存也会被正确释放,因为它将对象和控制块的分配和构造合并为一个原子操作。...下面是一个使用 std::make_shared 和直接初始化 std::shared_ptr 的例子: 使用 std::make_shared: auto ptr = std::make_shared...(arg1, arg2, arg3); 直接初始化 std::shared_ptr: std::shared_ptr ptr(new MyClass(arg1, arg2

    11210

    C++11 shared_ptr 原理与详细教程

    核心优势共享所有权:支持多指针共同管理同一资源自动释放:最后一个所有者销毁时自动释放资源灵活性:可与标准容器和算法无缝配合线程安全:引用计数的修改是原子操作,支持多线程环境自定义删除器:支持自定义资源释放逻辑二...(control block)管理引用计数和其他资源。...创建 shared_ptr 时,控制块和管理对象会在同一块内存中分配,减少内存碎片并提高缓存效率。...仅需原子性)减少计数使用 memory_order_acq_rel(确保资源释放的正确顺序)控制块的多态设计基类 ControlBlockBase 定义通用接口派生类 ControlBlock 处理具体类型和删除器支持不同类型的删除器和分配器拷贝与移动语义拷贝操作增加引用计数移动操作转移所有权...其核心特点包括:共享所有权:多个 shared_ptr 可指向同一对象自动释放:最后一个所有者销毁时释放资源线程安全:引用计数操作是原子的,支持多线程环境灵活性:支持自定义删除器和分配器配合 weak_ptr

    76010
    领券