热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

EffectiveC++随笔13to17资源管理

资源管理并不单指内存,这里的资源包括内存、文件描述器、互斥锁、图形界面中的字形与笔刷、数据库连接、网络sockets等,其中最常用的是内存资源。13.以对象管理资源为防止资源泄露的



资源管理并不单指内存,这里的资源包括内存、文件描述器、互斥锁、图形界面中的字形与笔刷、数据库连接、网络sockets等,其中最常用的是内存资源。


13.以对象管理资源

为防止资源泄露的一个简单方法是:使用RAII对象,(资源取得即初始化),通常在构造函数中分配资源,在析构函数中释放资源。这样做带来的好处是:对象在离开作用域时,会隐式调用析构函数,将内存释放,不必担心忘记将资源释放及提早return或出现异常导致资源未释放的问题。

RAII的一个例子是智能指针auto_ptr,智能指针的一个特点是:由于智能指针被销毁时会自动释放指向的内存,因此不允许两个指针指向同一块内存。在指针赋值时,ptr1=ptr2,ptr1接受ptr2的赋值后,ptr2会变成NULL,ptr1拥有该资源的唯一控制权,这一特性不同于普通指针。

若要完成两个指针指向同一内存的功能,可以使用shared_ptr,称为引用技术性智慧指针(RCSP),它追踪共有多少对象指向某笔资源,并在无人指向时释放该资源。

值得说明的一点是:使用智能指针完成动态分配数组是一个糟糕的想法,因为智能指针析构时调用的是delete而非delete[ ],这将只释放掉数组的头指针,而数组内存无法释放。若你有该需求,使用vector是个好的选择。


14.资源管理类中小心copy行为

复制RAII对象必须一并复制它所管理的资源,所以资源的copy行为决定了RAII对象的copy行为。当一个RAII对象被复制时,我们通常会考虑下面的策略:

(1)禁止复制

对于一些RAII对象,对其进行复制操作事实上并不合理(如互斥锁),此时我们应该禁止复制,实现方法之前有详述(重载复制构造函数设为private)。

(2)对底层资源使用“引用计数法”

有时候我们希望保留某资源,直至其最后一个调用者被销毁,类似于shared_ptr的机制。

这里的shared_ptr允许指定第二个参数,将一函数作为删除器,在调用者计数为零时,将会调用该删除器完成相应功能(本例中是解开互锁)



(3)复制底部资源

这要求复制时不仅复制资源管理对象,同时也复制其所包覆的资源。这种复制方式称为“深拷贝”。

(4)转移底部资源

auto_ptr是一个典型。


15.在资源管理类中提供对原始资源的访问

RAII给我们提供了一种管理内存的机制,但有时我们经常会遇到需要访问原始资源的问题,因此每一个RAII类应当提供一种访问其原始资源的方法如get()函数。对原始资源的访问可能经由显式转换或隐式转换,一般来说显式转换比较安全,但隐式转换对用户来说比较方便。

在这里插入图片描述

在这里插入图片描述


16.成对使用new和delete时要采取相同形式

delete与new一一匹配,delete[ ]与new一个数组一一匹配。

(来自C++ primer)

当new函数运行时,实际上发生三个步骤:

1.调用operator new的标准库函数,分配足够大的原始未类型化的内存,以保存指定类型的一个对象。

2.运行该类型的一个构造函数,使用指定初始化式构造对象

3.返回指向新分配并构造对象的指针

当delete函数运行时,实际上发生两个步骤:

1.对指针指向的对象调用适当的析构函数

2.调用operator delete的标准库函数释放对象使用的内存


17.以独立语句将newd对象置入智能指针

在这里插入图片描述

为什么上图的做法不是一个好的选择?

因为按需要本应按下图的顺序执行工作:

在这里插入图片描述

但C++并未定义其顺序,编译器完全可能以下面的顺序完成在这里插入图片描述

此时问题出现了,若第二步出现异常,则第三步不会运行,作为唯一能够控制该内存的智能指针并未建立,该块内存将永远不能被我们访问与释放。

因此我们应当将使用独立语句将其置入智能指针,以避免出现异常导致句柄丢失影响内存释放。

在这里插入图片描述



推荐阅读
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
    本文旨在全面介绍Windows内存管理机制及C++内存分配实例中的内存映射文件。通过对内存映射文件的使用场合和与虚拟内存的区别进行解析,帮助读者更好地理解操作系统的内存管理机制。同时,本文还提供了相关章节的链接,方便读者深入学习Windows内存管理及C++内存分配实例的其他内容。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • Day2列表、字典、集合操作详解
    本文详细介绍了列表、字典、集合的操作方法,包括定义列表、访问列表元素、字符串操作、字典操作、集合操作、文件操作、字符编码与转码等内容。内容详实,适合初学者参考。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
author-avatar
天蝎快乐公主_594
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有