首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【Example】C++ 标准库智能指针 unique_ptr 与 shared_ptr

在现代 C + + 编程中,标准库包含智能指针,智能指针可处理对其拥有的内存的分配和删除,这些指针用于帮助确保程序不会出现内存和资源泄漏,并具有异常安全。...C 样式编程的一个主要 bug 类型是内存泄漏。 泄漏通常是由于为分配的内存的调用失败引起的 delete new。 现代 C++ 强调“资源获取即初始化”(RAII) 原则。 其理念很简单。...--Microsoft Docs 为了支持对 RAII 原则的简单采用,C++ 标准库提供了三种智能指针类型: std::unique_ptr std::shared_ptr std::weak_ptr...此函数的速度更快,导致内存碎片更少,但在一次分配时不存在异常,而不是在另一种分配上。 通过使引用对象和更新智能指针中的引用计数的代码具有的更好的地址来提高性能。...make_shared如果对象需要自定义删除器,则不能使用,因为无法将删除器作为参数传递。

1.1K20

对象池的使用场景以及自动回收技术

不需要调用者在对象使用完成后,手动将对象归还给对象池,并且你可能要问: 针对不同类型的Object,是不是可以用模板去实现更加通用的实现一个对象池 构造函数的参数列表,也可以是任意的形式 自动回收的对象池...要实现自动回收的对象池,首先要了解unique_ptr和shared_ptr都可以自定义删除器,也就是说,比如当从对象池获取到的对象是用智能指针包裹的,一般默认的删除器为delete,那我们可以自义定删除器为...: 将这个对象重新放回到对象池....主要如下阐述: 因为我们需要把智能指针的默认删除器改为自定义删除器,用shared_ptr会很不方便,因为你无法直接将shared_ptr的删除器修改为自定义删除器,虽然你可以通过重新创建一个新对象,把原对象拷贝过来的做法来实现...而unique_ptr由于是独占语义,提供了一种简便的方法方法可以实现修改删除器,所以用unique_ptr是最适合的。

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

    智能指针在面试中得重要地位!

    和裸指针有相同的尺寸,甚至可以在内存和时钟周期紧张场合下使用 //情况1:std::unique_ptr是个只移动型别,不可以复制 //移动一个std::unique_ptr会将所有权从源指针移动到目标指针...资源析构采用 delete 运算符来实现,但可以指定自定义删除器 // 有状态的删除器和采用函数指针实现的删除器会增加 std::unique_ptr // 别的对象尺寸 // • std::unique_ptr...operator =() 重载了 = 赋值号,从而可以将 nullptr 或者一个右值 unique_ptr 指针直接赋值给当前同类型的 unique_ptr 指针。...{pw1, pw2 //但是请注意:对于具有不同自定义析构器型别的 std::unique_ptr来说,以上这些均无法实现 //因为自定义析构器的型别会影响 std::unqie_ptr的型别 //不同点...//注意自定义析构器可能是函数对象,函数对象可以包含任意数量的数据,这意味着它们的尺寸可能是任意大小 //std::shared_ptr如何能够在不使用更多内存的前提下,指涉到任意尺寸的析构器?

    1K20

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

    C++的智能指针是一种特殊的指针类型,它能够自动管理内存资源,避免常见的内存泄漏和多次释放等问题。C++11引入了三种主要的智能指针:unique_ptr、shared_ptr和weak_ptr。...支持移动语义:unique_ptr支持移动构造和移动赋值操作,可以将所有权转移给新的unique_ptr,而无需进行内存拷贝。...可自定义删除器:unique_ptr可以通过模板参数来指定一个删除器(deleter)函数对象,用于在释放内存时执行额外的清理操作。...不再拥有对象的所有权 std::cout std::endl; // 输出: 42 // 使用自定义删除器 struct Deleter {...unique_ptr超出作用域时会自动释放内存,同时调用自定义删除器 return 0; } 常见成员函数 operator*:解引用操作符,用于获取 unique_ptr 所指向对象的引用。

    1.1K20

    shared_ptr 和 unique_ptr 深入探秘

    在 unique_ptr 内部会保存类型为 T* 和 Deleter 的成员 ,分别表示保存的裸指针和删除器。...C++ 声明和定义最大的区别就是是否发生内存分配,当发生内存分配的时候,必须知道要分配多少内存,通常一个未定义的 struct,未指定长度的数组类型,都会引发 incomplete type 的问题。...ptr;因此可以对这个问题做定性:并不是 unique_ptr 需要知道析构函数,而是 unique_ptr 的默认删除器 Deleter 需要明确知道类型的析构函数。...block 的结构里,相当于做了一次 type erasure,把 Deleter 的类型从 shared_ptr 类型本身里面擦下去。...unique_ptr 相当于在编译时绑定了删除器。shared_ptr 保存的是一个控制块的指针。控制块包含的就是一个引用计数和一个原来对象的裸指针。

    45710

    C++相关基础知识总结笔记

    智能指针 智能指针是一种具有自动资源管理功能的指针,如 std::unique_ptr, std::shared_ptr,std::weak_ptr能够自动管理内存生命周期。...这意味着可以通过 std::move 将一个 std::unique_ptr 的所有权转移到另一个 std::unique_ptr。...删除器:std::unique_ptr 支持自定义删除器,可以用来执行额外的清理工作,如关闭文件句柄等。...volatile关键字的作用 volatile 关键字主要用于多线程环境中,用于标记一个变量,使得对该变量的读写操作不会被编译器或处理器优化而存储在寄存器中,而是每次都强制从主内存中加载最新的值。...但是: 删除元素:删除当前迭代器指向的元素会使该迭代器失效。但删除操作不会影响其他迭代器的有效性。 例如,std::map::erase 会使被删除元素的迭代器失效,但不影响其他迭代器。

    21330

    【C++高阶】:自定义删除器的全面探索

    删除器的基本概念 在C++中,智能指针(Smart Pointers)如std::unique_ptr和std::shared_ptr默认使用delete或delete[]来释放内存。...1.3 为什么需要自定义删除器 1.2.1 管理非堆内存资源 除了内存,智能指针还可以用于管理其他类型的资源,例如文件句柄、互斥锁或数据库连接。这些资源可能需要特定的释放机制。...function 需要多态删除器 高度灵活 性能和内存开销 2、自定义删除器的设计 2.1 函数对象(Functor)作为删除器 在C++中,函数对象(Functor)是一种非常灵活的机制,它允许我们将行为...使用std::unique_ptr(唯一指针)或std::shared_ptr(共享指针)时,你可以将函数对象作为第二个模板参数传递。...std::unique_ptr或std::shared_ptr的删除器。

    19310

    c++智能指针的理解与简易实现

    内存泄露会使该部分内存资源不可用,以及同样重要的,动态对象所持有的资源无法释放。而重复释放则可能会导致程序crash。 于是智能指针应运而生,承担了删除动态对象释放内存的责任。...考虑一种情况:如果一个函数同时出现了unique_ptr和unique_ptr的重载,并且尝试通过隐式转换调用,那么编译器无法推测应该转换为哪种类型。...--- 浅总结一下智能指针知识点 shared_ptr一般比unique_ptr更占用内存,但是如果在unique_ptr使用自定义析构器的话,那么情况可能不同。...针对shared_ptr,工厂函数只进行一次动态内存分配,分配效率高,同时也避免了裸指针方式两次分配中间因为异常导致的内存泄露。 如下场景不适合或谨慎使用make工厂函数: 自定义析构器。...工厂函数无法自定义析构器,所以这种场景就无法使用。

    76800

    C++的auto_ptr智能指针:从诞生到被弃用的历程

    std::cout std::endl;} // p离开作用域,自动删除指向的int对象int main() { func(); return 0;}auto_ptr对象p...在C++中,动态分配数组是一个常见的操作,但auto_ptr无法管理数组类型的内存。...如果尝试用auto_ptr来管理一个动态分配的数组,编译器将报错:std::auto_ptr p(new int[10]); // 错误,auto_ptr不支持数组这一限制使得auto_ptr...unique_ptr通过禁用拷贝构造函数和拷贝赋值运算符,确保了对象的所有权唯一性。同时,unique_ptr支持自定义删除器,可以方便地管理不同类型的资源。...C++17中的正式移除在C++17标准中,auto_ptr被正式从标准库中移除。这意味着在C++17及更高版本的代码中,使用auto_ptr将导致编译错误。

    14410

    为何优先选用unique_ptr而不是裸指针?

    在《拥抱智能指针,告别内存泄露》中说到了内存泄漏问题,也提到了C++中的智能指针基本原理,今天就来说说类模板unique_ptr。 在此之前,先回答读者的一个提问:C语言中该怎么办?... up(d);//空的unique_ptr 含义分别如下: T unique_ptr管理的对象类型 D 删除器类型 t unique_ptr管理的对象 d 删除器函数/function对象等,...后面我们也可以看到,与shared_ptr不同,unique_ptr在编译时绑定删除器,避免了运行时开销。...test(up);//试图传入unique_ptr,编译报错 std::coutstd::endl; return 0; } 上面的代码编译将直接报错。...为什么优先选用unique_ptr 回到标题的问题,问什么优先选用unique_ptr。

    1.8K00

    Chapter 4: Smart Pointers

    通用的例子是将 std::unique_ptr 作为返回层次结构中对象的工厂函数的返回类型,对于这样一个层次结构,工厂函数通常在堆上分配一个对象,然后返回指向该对象的指针,而工厂函数调用者则负责在使用完对象后...std::unique_ptr 设置自定义析构器后, std::unique_ptr 的大小不再等于原始指针的大小 当自定义析构器是函数指针时, std::unique_ptr 的大小从 1 个字长变为...具有和垃圾回收一样的自动资源管理,但时间可预测,而不是由垃圾回收器那种决定哪些内存在什么时候回收 一个通过 std::shared_ptr 访问的对象,它的生命周期由这些指针通过共享使用权来管理,没有特定的...自定义的析构器区别 对于 std::unique_ptr ,自定义析构器属于 std::unique_ptr 的一部分 对于 std::shared_ptr ,自定义析构器不属于 std::unique_ptr...std::shared_ptr 中,自定义析构器不是指针对象的一部分,也就不要求在编译生成的特定函数(析构函数,移动函数)对象中指针指向的类型是完整的 7.Summary std::unique_ptr

    1.6K20

    【CC++】——小白初步了解——内存管理

    堆区的内存分配效率较低,但灵活性高。 栈区(Stack): 用于函数调用时的临时存储,包括函数的局部变量、参数和返回地址。 栈区的内存由编译器自动分配和释放,具有后进先出的特点。...这种技术通常用于自定义内存池或优化程序性能。 7. 常见面试题 1.解释C++中new和malloc的区别 new: 分配内存并调用构造函数初始化对象。 返回对象的指针。 可以重载。...避免方法: 使用智能指针(如 std::unique_ptr 和 std::shared_ptr)来自动管理内存。...内存由编译器自动分配和释放。 具有后进先出的特点。 内存分配效率高,但大小有限。 堆区: 用于动态内存分配。 内存由程序员手动分配和释放。 大小不固定,可以动态增长或缩小。...内存分配效率较低,但灵活性高。 5.如何实现自己的内存池? 内存池是一种预分配大块内存以减少多次分配开销的方法。可以通过链表管理内存块,分配时从链表中取出一块内存,释放时将内存块重新挂回链表。

    12210

    【C++高阶】:智能指针的全面解析

    分配在静态或栈内存中的对象由编译器自动创建和销毁。对于栈对象,仅在其定义的程序块运行时才存在;static对象在使用之前分配,在程序结束时销毁。 除了静态内存和栈内存,每个程序还拥有一个内存池。...传统的C++程序员依赖new和delete(新建和删除)来手动管理内存,但是由于new和delete不能自动管理资源也不支持自定义删除器,导致使用该方式容易导致内存泄漏或是双重释放等问题。...初始化 std::unique_ptr是一个独占型的智能指针,它不允许其他的智能指针共享其内部的指针,可以通过它的构造函数初始化一个独占智能指针对象,但是不允许通过赋值将一个unique_ptr赋值给另一个...指定删除器 unique_ptr指定删除器和shared_ptr指定删除器是有区别的,unique_ptr指定删除器的时候需要确定删除器的类型,所以不能像shared_ptr那样直接指定删除器 int...,后面我会单独出一篇关于自定义删除器的博客,敬请期待咯!!!

    33510

    智能指针探究

    ,并且使用new int动态分配内存来存储一个int类型的对象 第四行代码创建另一个unique_ptr对象p2,并且使用std::move()将p1转化为右值引用并传递给p2的移动构造函数,...,先减shared_ptr pa(new B());,发现堆内存引用从2到1,再减shared_ptr pa(new A());发现也是从2到1,右边这两个堆内存,只有两个互相指,其他人不知道了...因此,在使用 detach() 方法时应谨慎 自定义删除器 智能指针:能够保证资源的绝对释放,里面默认都是delete ptr释放资源的 但不是所有的资源都是能够通过delete释放的,毕竟资源那么多种类...先讲讲智能指针内部是咋回事吧 unique_ptr shared_ptr 一个不带计数,一个带计数 他们两个都是可以带自定义删除器的 看他们的源码 ~unique_ptr(){ 是一个函数对象的调用...第一个参数是指针所指向的类型,即 int。第二个参数是删除器类型,即 function。

    9210

    【C++】智能指针 && 守卫锁

    unique_ptr 还支持移动语义进行 std::move,可以将所有权转移给另一个 unique_ptr,从而实现资源的转移和管理。 ​...shared_ptr sp2(new string[10]); // 肯定会报错,因为是自定义类型 return 0; } ​ 上述代码运行之后,对于 sp1 来说,不同的编译器可能会有不同的结果...但是我们自己来实现这个功能并不简单,因为这个删除器是要给析构函数使用的,而如果像 std::shared_ptr 一样,通过第二个参数传过去,那么我们是要在构造函数接收,但是要在析构函数使用,那么我们就得有一个删除器的类型对象...,那么我们就得在重载的构造函数写上一个新的模板参数,假设模板参数是 class D,但是有一个问题,这个 D 类型的删除器模板是这个构造函数的啊,这个时候就不好直接在 std::shared_ptr 中声明一个...库里面的做法是将引用计数和这个删除器单独作为一个类进行封装,这样子实现起来是比较复杂的! ​

    5410

    C++智能指针

    这时我们会想:当remodel这样的函数终止(不管是正常终止,还是由于出现了异常而终止),函数体内的局部变量都将自动从栈内存中删除,因此指针ps占据的内存将被释放,如果ps指向的内存也被自动释放,那该有多好啊... u_i2(new int(4));//创建时指定动态对象 unique_ptr u(d); //创建空unique_ptr,执行类型为T的对象,用类型为D的对象d来替代默认的删除器...unique_ptr默认的资源删除操作是delete/delete[],若需要,可以进行自定义: void end_connection(connection *p) { disconnect(*p);...如果函数使用new分配内存,并返还指向该内存的指针,将其返回类型声明为unique_ptr是不错的选择。这样,所有权转让给接受返回值的unique_ptr,而该智能指针将负责调用delete。...前面说过,编译器将发现错误使用unique_ptr的企图。

    3.5K30

    彻底搞懂之C++智能指针

    所有实例均指向同一个对象,并共享对一个“控制块”(每当新的 shared_ptr 添加、超出范围或重置时增加和减少引用计数)的访问权限。 当引用计数达到零时,控制块将删除内存资源和自身。...我简单的总结下就是:将基本类型指针封装为类对象指针(这个类肯定是个模板,以适应不同基本类型的需求),并在析构函数里编写delete语句删除指针指向的内存空间。...但是可以进行移动构造和移动赋值操作 3、保存指向某个对象的指针,当它本身被删除释放的时候,会使用给定的删除器释放它指向的对象 用法: std::unique_ptrp1(new int(5))...但是,你可以使用 weak_ptr 来尝试获取用于初始化的的新副本 shared_ptr 。 如果已删除内存,则的 bool 运算符将 weak_ptr 返回 false 。...如果函数使用new分配内存,并返还指向该内存的指针,将其返回类型声明为unique_ptr是不错的选择。这样,所有权转让给接受返回值的unique_ptr,而该智能指针将负责调用delete。

    3.9K10

    C++对象内存池

    对象内存池(Object Pool)是一种设计模式,旨在通过重用对象来提高性能,减少内存分配和释放的开销。...在 C++ 中,由于其手动内存管理的特性,使用对象内存池可以显著提高程序的效率,尤其是在需要频繁创建和销毁对象的场景中。 1....对象内存池的概念 对象内存池的核心思想是维护一个对象的集合(池),当需要使用对象时,从池中获取一个对象,而不是每次都创建新的对象。当对象不再使用时,它会被放回池中,而不是被销毁。...这样可以减少内存分配和垃圾回收的频率。 1.1 主要组成部分 对象池:存储可重用对象的集合。 对象管理器:负责对象的分配和回收。 对象:实际使用的实例。 2....C++ 中的对象内存池实现 2.1 基本实现 以下是一个简单的 C++ 对象内存池的实现示例: #include #include #include <memory

    17210

    【重学C++】02 脱离指针陷阱:深入浅出 C++ 智能指针

    可以在资源(原生指针对应的对象)生命周期结束时自动释放内存。C++标准库中,提供了两种最常见的智能指针类型,分别是std::unique_ptr 和 std::shared_ptr。...将 std::unique_ptr 重置为nullptr或管理另一个对象。...采用引用计数的方式管理资源对象的生命周期,通过分配一个额外内存当计数器。...否则,将计数器指针置为nullptrshared_ptr使用注意事项避免循环引用由于 shared_ptr 具有共享同一个资源对象的能力,因此容易出现循环引用的情况。...: 2wp is expired: 1回到shared_ptr的循环引用问题,利用weak_ptr不会增加shared_ptr的引用计数的特点,我们将Node.next的类型改为weak_ptr, 避免

    43600
    领券