智能指针之unique_ptr(删除器、尺寸)08

2023-10-27

一 unique_ptr

1 unique_ptr删除器

unique_ptr和shared_ptr一样,默认删除器都是使用delete,所以当我们创建的是一个数组或者文件这些时,显然delete是无法有效回收的。
删除器是一个可调用对象,其中可调用对象可以是普通函数,或者重载了()括号的类,或者lambda表达式等等。
unique_ptr删除器比shared_ptr多了一步,先要在类型模板参数中传递进去类型名,然后在参数中再给具体的其函数名。

void mydeleter(string *pdel)
{
    delete pdel;
    pdel = nullptr;
    //可以打印日志
    cout<<"mydeleter"<<endl;
}
 
void test19(){

    // a.1
    typedef void(*fp)(string *);
    unique_ptr<string, fp> ps1(new string("good luck"), mydeleter);
 
    //a.2
    using fp2 = void(*)(string *);
    unique_ptr<string, fp2> ps2(new string("good luck"), mydeleter);
 
    //a.3
    typedef decltype(mydeleter)* fp3; //decltype()返回函数类型void(string *),所以要加*,现在fp3应该是void *(string *)
    unique_ptr<string, fp3> ps3(new string("good luck"), mydeleter);
 
    //a.4
    unique_ptr<string, decltype(mydeleter)*> ps4(new string("good luck"), mydeleter);
 
    //a.5,lambda表达式,可以理解成operator()类类型对象
    auto mydella = [](string *pdel)->void{
        delete pdel;
        pdel = nullptr;
        cout<<"mydella"<<endl;
    };
    //注意,lambda表达式mydella被编译器理解成对象(即ps5的参2),所以我们类型不能加*,否则地址与对象不匹配
    //而上面的函数名mydeleter代表是首地址,需要加*地址符号进行匹配。(对象不是对象,&对象才是地址)
    unique_ptr<string, decltype(mydella)> ps5(new string("good luck"), mydella);
 
}

在这里插入图片描述

指定删除器额外说明

  • 1)shared_ptr:就算两个shared_ptr指定的删除器不同,指向他们指向的对象相同,那么他们属于同一个类型。可以放到同一个容器中。
  • 2)unique_ptr:指定unique_ptr中的删除器会影响unique_ptr类型。所以,从灵活性上来讲,shared_ptr更灵活。unique_ptr如果删除器不同,那么就等于整个unique_ptr类型不同,这种类型不同的unique_ptr智能指针是没法放到同一个容器中的。

2 尺寸问题

当我们在上面代码添加求智能指针的所占字节数,如下:

//开头先求原指针所占字节数
string *str = NULL;
cout<<"未加删除器的指针所占字节数="<<sizeof(str)<<endl;

//然后在每个ps下面各自求出对应智能指针的所占字节数。这里只列出一个。
int ilen = sizeof(ps1);
cout << "ps1的所占字节数=" << ilen << endl;

结果:注意我的是64位下测试,所以原指针所占字节数为8,若是VS的32位下,原指针占4字节。
在这里插入图片描述
上面结果明显看到,lambda表达式,尺寸没有变化,其余都发现变化。

所以可以总结:
如果你增加了自己的删除器,则unique_ptr的尺寸可能增加,也可能不增加。具体如下:

  • 1)用lambda表达式,尺寸没有变化。
  • 2)定义一个函数作为删除器,尺寸发生变化。增加字节的对效率有影响。shared_ptr不管你指向什么删除器,shared_ptr的尺寸大小都是裸指针的2倍。

3 智能指针的总结

目前开发我们只需要用到shared_ptr, unique_ptr已经足够,weak_ptr基本不需要使用,它更多时候是给那些开发标准库的人使用。
然后shared_ptr, unique_ptr的选择主要看下面的区别:

  • 1)如果程序要是用多个指向同一个对象的指针,应选择shared_ptr。
  • 2)如果程序不需要多个指向同一个对象的指针,应该首选unique_ptr。

讲到本篇,智能指针的所有知识点结束,我以前也总结过智能指针,但是不够全面,目前这8篇已经非常全面了,智能指针各种使用场合,和语法都包含进去,总的来说写这八篇文章还是有点难度的,原因是C++的新语法越来越看不懂,有点吃力。完结。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

智能指针之unique_ptr(删除器、尺寸)08 的相关文章

  • 在 JavaScript 中引用 C# 变量

    我已经阅读了很多线程 但我不明白为什么这不起作用 我正在创建一个将用作导航栏的 SharePoint Web 部件 一切都很顺利 直到我尝试在 JS 代码中引用 C 变量 这是来自 VisualWebPart1UserControl asc
  • 访问特征矩阵的行向量时复制或引用

    我正在使用的代码Eigen http eigen tuxfamily org index php title Main Page矩阵库 我注意到在整个代码中 有如下访问器 RowVector3f V size t vertex index
  • 函数“sum”的隐式声明在 C99 中无效

    我一直在寻找解决方案 但没有找到任何有帮助的东西 我收到以下错误 Implicit declaration of function sum is invalid in C99 Implicit declaration of function
  • 为什么在排序输入上插入到树中比随机输入更快?

    现在我一直听说从随机选择的数据构建二叉搜索树比有序数据更快 这仅仅是因为有序数据需要显式重新平衡以将树高度保持在最低限度 最近我实现了一个不可变的treap http en wikipedia org wiki Treap 一种特殊的二叉搜
  • 如何在 Asp.Net Core 6 中向类型化 HttpClient 添加承载令牌身份验证

    我正在尝试使用 ASP Net Core 6 设置一个 Web api 以便用户可以到达我的端点 然后我使用特权帐户在幕后的 D365 中执行一些工作 我正在使用类型化的 HTTP 客户端 但我不确定如何插入承载身份验证 以便来自该客户端的
  • 如何将 mat 转换为 array2d

    我为dlib http dlib net face landmark detection ex cpp html那里的面部地标代码使用 array2d 来获取图像 但我喜欢使用 Mat 读取图像并转换为 array2d 因为 dlib 仅支
  • C 中的双重否定:是否保证返回 0/1?

    Is x 标准保证返回0 1 请注意 我是not询问 C 其中定义了 bool 类型 是的 在 C99 中 请参阅 6 5 3 3 4 逻辑非运算符的结果 是0如果其操作数的值比较 不等于0 1如果其操作数的值比较等于 0 结果具有类型in
  • 无法在 Visual Studio 和 vcpkg 中构建 cmake 项目(致命错误 C1083)

    我今天安装了vcpkg 启用了与Visual Studio的集成 即 vcpkg集成安装 并开始安装库 我基本上安装了 cpprestsdk 并触发了 boost 库的安装 然后我在 Visual Studio CMake 中打开该项目 当
  • Moq - 是否可以在不使用 It.IsAny 的情况下设置模拟

    我一直使用 Moq 进行单元测试 有时我会嘲笑有很多参数的方法 想象一下这样的方法 public class WorkClient public void DoSomething string itemName int itemCount
  • 这个元组创建习惯有名字吗?

    On the 增加邮件列表 http lists boost org Archives boost 2014 06 214213 php LouisDionne 最近发布了以下创建类似元组的实体的巧妙技巧 include
  • 我应该使用 Helgrind 还是 DRD 进行线程错误检测?

    好像Valgrind http valgrind org docs manual manual html有两个工具都可以进行线程错误检测 Helgrind http valgrind org docs manual hg manual ht
  • C# 中的类和模块有什么用

    有人可以解释一下类和模块之间的区别吗 你什么时候使用其中一种而不是另一种 我正在使用 C 更新 我的意思是相当于 VB 模块的 C 版本 这在很大程度上取决于您所指的 模块 Visual Basic 的模块 C 中没有真正等效的 VB Ne
  • C# 从今天起 30 天

    我需要我的应用程序从今天起 30 天后过期 我会将当前日期存储在应用程序配置中 如何检查应用程序是否已过期 我不介意用户是否将时钟调回来并且应用程序可以正常工作 用户太愚蠢而不会这样做 if appmode Trial string dat
  • 什么是 C++11 扩展 [-Wc++11-extensions]

    我需要一些帮助来了解此错误发生的位置 警告 非静态数据成员的类内初始化是 C 11 扩展 Wc 11 extensions 这是它来自的代码部分 typedef struct Hand bool straight false bool fl
  • 来自用户定义文字的整数字符序列,以字符串作为参数

    目前 只有双精度数可以在用户定义的文字中生成字符模板 template
  • 没有 FPU 的处理器中的浮点计算

    是否可以在没有浮点单元的嵌入式处理器中执行浮点运算 是的 您只需要在软件中完成即可 你的编译器可能会提供支持 http gcc gnu org onlinedocs gccint Soft float library routines ht
  • 如何使用 MongoDB 实现 ASP.NET Core 3.1 Identity?

    是一个 API 用于简化后端和逻辑代码来管理用户 密码 个人资料数据 角色 声明 令牌 电子邮件确认等 对于 Visual Studio 来说 支撑脚手架 https learn microsoft com en us aspnet cor
  • OpenSSL:无需 SSL_read() / SSL_write() 即可执行加密/解密

    我已经用 C 语言编写了一个基于事件的网络库 现在我想通过 OpenSSL 添加 SSL TLS 支持 而不是使用SSL read and SSL write 我宁愿让 OpenSSL 只执行传出 传入数据的加密 解密 让我自己传输 接收数
  • 如何在c#中获取斐波那契数

    伙计们 我有一个关于斐波那契的问题 如何获得斐波那契数列 该数字也将以用户输入结束 例如 如果我输入 21 则输出必须为 0 1 1 2 3 5 8 13 21 这是我的代码 static void Main string args int
  • Cordova 上的 ClearCookiesAsync()

    我正在尝试使用 wp8 cordova 中的插件来清除 WebBrowser cookie 我已经让它与 JavaScript 进行通信 并且我的 c 文件中有类似这样的内容 using WPCordovaClassLib Cordova

随机推荐

  • 关于codeblocks出现can't find compiler的解决方法

    关于codeblocks不能找到编译器的问题我来介绍一下解决的方法 1 首先要确定你的codeblocks是自带编译器的版本 你可访问codeblocks的官网 www codeblocks org 来到下载页面 如下图 点击第一个Down
  • 策略模式+Spring——让我们的代码更加高大上一点

    if else if else 代码是实际的项目代码中出现的比例还是蛮高的 特别是针对一些业务需求根据不同类型来进行不同的业务处理 针对这种业务模型 我们来试着使用策略模式结合Spring来优化我们的代码 让代码更加高大上一点 为了更好得结
  • n的阶乘求解方法

    n 的阶乘求解方法有以下三种 第一种通过递归计算 n int input def N a 定义一个函数进行阶乘计算 if a 1 return a else return N a 1 a print N n 第二种方法就是调用math库 通
  • 狂神说Mybatis最全课堂笔记

    Mybatis 自己整理的狂神说Mybatis学习笔记 环境 JDK1 8 Mysql 5 7 maven 3 6 1 IDEA 回顾 JDBC Mysql Java基础 Maven Junit SSM框架 配置文件 最好的方式 看官方文档
  • 小程序,压缩图片

    我们在小程序上 直接上传手机相册及拍照的图片时 因为图片过大 如10m 手机端不像我们再计算机上传输那么快 也没那么稳定 解决办法 在图片上传前压缩图片 压缩图片就是将图片尺寸 图片质量降低 把这两个指数降低到合适的规格 1 首先在 wxm
  • RK3399 Linux-SDK mipi屏幕驱动及调试

    一 流程及通路 我接触到的三款mipi屏幕 基本的点亮流程都是很一致的 就是背光使能 背光点亮 屏幕使能 reset引脚按指定时序 波形拉高或拉低 初始化序列命令发送 3399的linuxSDK中 包含一种类似通用的屏幕驱动 本文档以使用此
  • [Eagle API]使用python打印eagle指定文件夹下的所有子文件名

    api https www yuque com augus gsjgn eagle api pq0y2y 官方api源码 var requestOptions method GET redirect follow fetch http lo
  • mojo安装

    docker安装mojo 官网 https developer modular com login 很奇怪登录页面不显示 类似于网站劫持 docker 安装mojo带jupyterlab的方式 https hub docker com r
  • const_cast

    const cast是一种C 运算符 主要是用来去除复合类型中const和volatile属性 没有真正去除 变量本身的const属性是不能去除的 要想修改变量的值 一般是去除指针 或引用 的const属性 再进行间接修改 用法 const
  • 烂泥:查看服务器的BIOS是否开启CPU虚拟化

    本文由秀依林枫提供友情赞助 首发于烂泥行天下 有关CPU是否支持虚拟化 我们可以通过相关的命令和软件进行查看 在windows系统下 我们可以使用CPU Z这个软件 如下图 在linux系统下 我们可以通过查看 proc cpuinfo文件
  • Python图像处理之图片文字识别(OCR)

    OCR与Tesseract介绍 将图片翻译成文字一般被称为光学文字识别 Optical Character Recognition OCR 可以实现OCR 的底层库并不多 目前很多库都是使用共同的几个底层OCR 库 或者是在上面进行定制 T
  • Python自动化处理邮件

    Python处理QQ邮箱邮件 以Chrome浏览器为例 需下载chromedriver exe下载地址 根据自己电脑上的Chrome版本下载相应的chromedriver exe 打开的Chrome浏览器主界面的地址栏输入网址 chrome
  • 计算机原理-数据

    数据 二进制 十进制 人类use 十六进制 2 4 16 是权 1011 011 2 3 0 2 2 2 1 2 0 0 2 1 1 2 2 1 2 3 8 0 2 1 0 0 25 0 125 27 375 七进制转十进制 权不一样 60
  • Centos7离线安装MySQL

    前言 离线安装的方式 很多人 包括我自己是很难的 yum的方式简单轻松 作者之前离线安装oracle的时候 因为关键的rpm包不齐 通过查安装日志一个一个的下离线包 反复安装3天才完成离线模式安装 今天总结下MySQL的离线安装步骤 环境
  • 【Unreal】TArray与std::vector之间转换

    std vector data 返回一个指向内存数组的直接指针 该内存数组由vector内部用于存储其拥有的元素 TArray GetData 同理 FMemory Memcpy 则将指定位置和大小的数组的内存空间拷贝 覆盖 到另一处指定的
  • 第五周课程总结&试验报告(三)

    Java实验报告 班级 计科二班 学号 20188423 姓名 邹健 完成时间 2019 9 27 评分等级 实验三 String类的应用 一 实验目的 1 掌握类String类的使用 2 学会使用JDK帮助文档 二 实验内容 1 已知字符
  • Vcpkg介绍及使用

    Vcpkg用于在Windows Linux Mac上管理C和C 库 极大简化了第三方库的安装 它由微软开源 源码地址 https github com Microsoft vcpkg 最新发布版本为2023 04 15 Release 它的
  • 【译】Filed Play:简介

    引子 在尝试数学函数可视化的时候 发现了一个有趣的库 Field Play 对 README 中的说明进行部分翻译记录 做个初步了解 Origin My GitHub What 让我们为网格上的每个点指定一个向量 1 0 这意味着我们有一个
  • JavaScript Function、函数声明、函数表达式

    JavaScript Function 函数声明 函数表达式 Function 对象 Function 构造器会创建一个新的 Function 对象 在 JavaScript 中每个函数都是一个 Function 对象 使用 Functio
  • 智能指针之unique_ptr(删除器、尺寸)08

    一 unique ptr 1 unique ptr删除器 unique ptr和shared ptr一样 默认删除器都是使用delete 所以当我们创建的是一个数组或者文件这些时 显然delete是无法有效回收的 删除器是一个可调用对象 其