【Effective C++】资源管理
资源:动态分配的内存、文件描述器、互斥锁、图形界面中的字型与笔刷、数据库连接以及网络sockets等,无论哪一种资源,重要的是,当你不再使用它时,必须将它还给系统。
条款13:以对象管理资源
当我们向系统申请资源后,一定要记得释放,不然就容易发生内存泄漏。但是意识到这样一件事并不是很容易,比如我们是通过一个函数来动态分配内存并返回一个指针。
Investment* ceateInvestment();// 返回指针,指向动态分配对象
void f()
{
Investment* pInv = ceateInvestment();
// ...
delete pInv;
}
即使像上面的代码一样,我们在用完指针pInv后,我们调用了delete,但是还是可能出问题,有时候我们可能在...的部分提前return或跳出了循环,甚至在该部分发生了异常,这都导致delete根本执行不到。
解决方法是我们把指针放在一个资源管理的类里,让类对象在生命结束的时候,会自动调用析构函数,而析构函数里会执行delete。
两个常被使用的RAII类分别是:shared_ptr和unique_ptr,它们间不同的是shared_ptr允许存在同一内存区域的多个指针拷贝,而unique_ptr只允许一份指针指向对象,当uniuqe_ptr发生赋值操作时,用于赋值的指针将会变成null。
条款14:在资源管理类中小心copying行为
在实际管理资源时,并非所有的资源都是堆内存(heap),所以unique_ptr或shared_ptr这样的智能指针往往不适合作为资源管理者。
比如你需要控制类型为Mtux的互斥器对象,共有lock和unlock两函数可用,你需要保证的就是不要忘记将一个被锁住的Mutex解锁,我们的想法的主旨就是:资源在构造期间创建,在析构期间释放。
class Lock
{
public:
explicit Lock(Mutex* pm) :mutexPtr(pm){ lock(mutexPtr;) }// 获得资源
~Lock(){ unlock(mutexPtr); }// 释放资源
};
这样虽然很好,但是如果Lock被复制了,就会发生问题。它可能会引起对了一Mutex解锁两次。
常见的解决方案有2种:一种是禁止复制;第二种是对底层资源祭出“引用计数法”,这也是shared_ptr实现原理。
条款15:在资源管理类中提供对原始资源的访问
很多API接口往往要求访问原始资源,所以每一个RAII class应该提供一个“取得其所管理之资源”的办法,比如提供一个get函数。
对原始资源的访问可能经由显式转换或隐式转换。一般而言显式转换比较安全,但隐式转换对客户比较方便。
条款16:成对使用new和delete时要采用相同形式
如果你在new表达式中使用[],必须在相应的delete表达式中使用[]。如果你在new表达式中不使用[],一定不要在相应的delete表达式中使用[]。
string* stringPtr1 = new string;
string* stringPtr2 = new string[100];
delete stringPtr1; // 删除一个对象
delete[] stringPtr2; // 删除一个由对象组成的数组
条款17:以独立语句将newed对象置入智能指针
假设我们有个函数用来控制程序的优先权,另一个函数用来在某个动态分配所得到的Wieget上进行某些带有优先权的处理:
int priority();
void processWidget(shared_ptr<Widget>pw, int priority);
现在假如我们这样调用它:
processWidget(share_ptr<Widget>(new Widget),priotrity());
在调用processWidget之前,编译器必须创建代码,做以下三件事:
- 调用priority
- 执行”new Widget”
- 调用shared_ptr构造函数
C++编译器并不保证上次代码执行的次序,但有一点可以保证,那就是new Widget肯定发生成share_ptr构造函数之前。
假如priority发生在第二步,并且执行过程中发生了异常,那就有可能资源不能正常的释放。
避免这种情况,就需要使用分离语句,先创建Widget,然后再将它置入一个智能指针内,然后再把那个智能指针传给processWidget。
【Effective C++】资源管理的更多相关文章
- Effective C++ ——资源管理
条款13:以对象来管理资源 在C++中我们经常会涉及到资源的申请与申请,一般都是由关键字new 和 delete来操作的,两者都是成对存在的,缺一不可,否则会出现意想不到的问题,例如: class I ...
- Effective C++ —— 资源管理(三)
条款13 : 以对象管理资源 假设有如下代码: Investment* createInvestment(); //返回指针,指向Investment继承体系内的动态分配对象,调用者有责任删除它 vo ...
- C++笔记--thread pool【转】
版权声明:转载著名出处 https://blog.csdn.net/gcola007/article/details/78750220 背景 刚粗略看完一遍c++ primer第五版,一直在找一些c+ ...
- c++内存管理学习纲要
本系列文章,主要是学习c++内存管理这一块的学习笔记. 时间:6.7-21 之下以技术内幕的开头语,带入到学习C++内存管理的技术中吧: 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题 ...
- Effective C++(15) 在资源管理类中提供对原始资源的访问
问题聚焦: 资源管理类是为了对抗资源泄露. 如果一些函数需要访问原始资源,资源管理类应该怎么做呢? 关于资源管理的概念总是显得那么的高大上,其实只是抽象一点. 下面用 ...
- Effective C++(14) 在资源管理类中小心copying行为
问题聚焦: 上一条款所告诉我们的智能指针,只适合与在堆中的资源,而并非所有资源都是在堆中的. 这时候,我们可能需要建立自己的资源管理类,那么建立自己的资源管理类时,需要注意什么呢?. ...
- 《Effective C++》第3章 资源管理(2)-读书笔记
章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...
- 《Effective C++》第3章 资源管理(1)-读书笔记
章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...
- Effective C++笔记:资源管理
资源:动态分配的内存.文件描述器.互斥锁.图形界面中的字型与笔刷.数据库连接以及网络sockets等,无论哪一种资源,重要的是,当你不再使用它时,必须将它还给系统. 条款13:以对象管理资源 当我们向 ...
- [Effective C++ --015]在资源管理类中提供对原始资源的访问
引言 资源管理类是防止资源泄漏的有力武器,但是许多APIs直接指涉资源,除非你发誓永不使用这样的APIs,否则只得绕过资源管理对象(resource-managing objects)直接访问原始资源 ...
随机推荐
- git-版本管理工具的介绍+发展史+分布式版本控制系统和集中式版本控制系统的区别
一.版本管理工具的介绍: 1.备份文件: 2.记录历史: 3.多端共享: 4.团队协作: 二.版本管理工具的发展史: 1.cvs: 集中式 1985: 2.svn: 集中式 2000: 3 ...
- 新华三孟丹:NFV资源池实现中的技术探讨
近日,在第三届未来网络发展大会SDN/NFV技术与应用创新分论坛上,新华三解决方案部架构师孟丹女士发表了主题为<NFV资源池实现中的技术探讨>的主题演讲. 孟丹指出,新华三的NFV核心理念 ...
- Java中ArrayList的初始容量和容量分配
1.实例化ArrayList时默认不输入大小是10个,并且如果增加到11个时不会报错,会自动扩容. 2.获取指定索引的值时就必须保证ArrayList有这么多个. 3.推荐在new ArrayList ...
- tensorflow global_variables_initializer()
老版本为 init = tf.initialize_all_variables() 新版本为 init = tf.global_variables_initializer()
- DAO 层实现
一.实验介绍 1.1 实验内容 本节课程主要利用 MyBatis 框架实现 DAO 层. 1.2 实验知识点 MyBatis 框架 MySQL 1.3 实验环境 JDK1.8 Eclipse Java ...
- cocos2d-x-3.x bringToFront & sendToBack实现
void Node::bringToFront(void) { auto parent = this->getParent(); if (parent != nullptr && ...
- 最长连续序列(Longest Consecutive Sequence)
Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...
- cocos2d-x入口类
上一篇文章中有一个在栈中创建的实例--AppDelegate.这个类的初始化使cocos2d-x的程序能够执行起来.由于它是继承于CCApplication类.而执行的run方法就是在此类中实现的. ...
- ok6410[002] ubuntu1604系统下搭配ckermit和dnw基于RAM的裸机程序调试环境
ubuntu1604系统下搭配ckermit和dnw基于RAM的裸机程序调试环境 系统: ubuntu16.04 裸板: 飞凌公司OK6410开发板 目标:搭建基于ubuntu1604系统和基于RA ...
- gulp css html image js 合并压缩
安装node.js npm 以及安装gulp等方法我就不在这里赘述了. 接下里我主要介绍的是Gulpfile文件里面的配置该如何书写. var gulp = require('gulp');//引 ...