Effective C++ 3.资源管理】的更多相关文章

条款13:以对象管理资源 为了防止资源泄漏,请使用RAII(Resource Acquisition Is Initialization)对象,在构造函数里面获得资源,在析构函数里面释放资源 auto_ptr,shared_ptr,unique_lock都是RAII类. 一个对象只能由单一auto_ptr指向,不可让多个auto_ptr同时指向同一对象. 通过copy构造函数或者copy assignment操作符赋值auto_ptr,被复制的auto_ptr会变成null,复制所得的auto_…
资源:动态分配的内存.文件描述器.互斥锁.图形界面中的字型与笔刷.数据库连接以及网络sockets等,无论哪一种资源,重要的是,当你不再使用它时,必须将它还给系统. 条款13:以对象管理资源 当我们向系统申请资源后,一定要记得释放,不然就容易发生内存泄漏.但是意识到这样一件事并不是很容易,比如我们是通过一个函数来动态分配内存并返回一个指针. Investment* ceateInvestment();// 返回指针,指向动态分配对象 void f() { Investment* pInv = c…
所谓资源,就是一旦用了它,将来必须还给系统.C++中的资源有:内存.文件描述符.互斥锁.数据库连接.网络socket等. 13:以对象管理资源 1:像下面这个函数: void f() { Investment *pInv = createInvestment(); ... delete pInv; } 这个函数中,会有若干情况的发生导致无法执行delete语句,比如”...”内可能有一个过早的return语句:或者createInvestment和delete位于某个循环内,而该循环由于某个co…
//条款13:以对象管理资源 // 1.C++程序中最常使用的资源就是动态分配内存,并且还包括文件描述器,互斥锁,GDI对象.数据库连接.网络socket等.不管哪一种资源,当不再使用的时候必须将其归还给系统. // 2.诸如以下代码: void fun(int *p) { ... ... delete p; }//以上代码中,p是指向动态分配的内存,在此函数中对p进行使用和释放,但是在函数中可能有一个过早的return语句导致delete语句不能被执行,或者产生一个异常而导致delete语句不…
对象管理资源 createInvestment 函数作用时创建一个invest对象: void f() { Investment *pInv = createInvestment(); // call factory function ... // use pInv delete pInv; // release object } 既然f函数中创建对象,销毁对象的责任也应该由它来承担,但是如果“……”区域出现异常或return提前执行,delete将被跳过,从而造成严重的内存泄露,为了确保无论发…
  问题聚焦:     资源管理类是为了对抗资源泄露.     如果一些函数需要访问原始资源,资源管理类应该怎么做呢?        关于资源管理的概念总是显得那么的高大上,其实只是抽象一点. 下面用一个例子还说明本节的主题: 在前面 Effective C++(13) 用对象管理资源 中我们提到过,使用智能指针保存工厂函数返回的结果 std::tr1::shared_ptr<Investment> pInv(createInvestment()); //加入有某个函数,用来处理Investm…
问题聚焦:     上一条款所告诉我们的智能指针,只适合与在堆中的资源,而并非所有资源都是在堆中的.     这时候,我们可能需要建立自己的资源管理类,那么建立自己的资源管理类时,需要注意什么呢?. 在详述这一章的主题之前,先回忆一下上一节所提到的一个名词——RAII(Resource Acquisition Is Initialization) 含义就是:资源取得时机便是初始化时机. 如果上一节对这个观念的理解还不是很深的话,那么下面这个例子可以让你更好地理解. Demo 假设我们使用C AP…
章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(2)-读书笔记 <Effective C++>第3章 资源管理(1)-读书笔记 <Effective C++>第3章 资源管理(2)-读书笔记 <Effective C++>第4章 设计与声明(1)-读书笔记 <Eff…
章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(2)-读书笔记 <Effective C++>第3章 资源管理(1)-读书笔记 <Effective C++>第3章 资源管理(2)-读书笔记 <Effective C++>第4章 设计与声明(1)-读书笔记 <Eff…
资源:动态分配的内存.文件描述器.互斥锁.图形界面中的字型与笔刷.数据库连接以及网络sockets等,无论哪一种资源,重要的是,当你不再使用它时,必须将它还给系统. 条款13:以对象管理资源 当我们向系统申请资源后,一定要记得释放,不然就容易发生内存泄漏.但是意识到这样一件事并不是很容易,比如我们是通过一个函数来动态分配内存并返回一个指针. Investment* ceateInvestment();// 返回指针,指向动态分配对象 void f() { Investment* pInv = c…
引言 资源管理类是防止资源泄漏的有力武器,但是许多APIs直接指涉资源,除非你发誓永不使用这样的APIs,否则只得绕过资源管理对象(resource-managing objects)直接访问原始资源(raw resources). 例如在条款13中引入了智能指针如auto_ptr或tr1::shared_ptr保存factory函数如createInvestment的调用结果: std::tr1::shared_ptr<Investement> pInv(createInvestment()…
第一节 <背景> 条款13中讲到“资源取得的时机便是初始化时机”并由此引出“以对象管理资源”的概念.通常情况下使用std中的auto_ptr(智能指针)和tr1::shared_ptr(引数智能指针)作为管理资源的对象.事实上,这种管理方法十分有效.但是,auto_ptr和tr1::shared_ptr只能管理基于堆(heap-based)的资源,而非heap-based的资源却往往不适合.因此,有的时候你需要建立自己的资源管理类.本文介绍的内容是在你建立自己的资源管理类时应该注意的事项. 第…
条款13:以对象管理资源 许多资源被动态分配于heap内而后被用于单一区块或函数内.它们应该在控制流离开那个区块或函数时被释放.标准程序库提供的auto_ptr正是针对这种形式而设计的特制产品.auto_ptr是个类指针对象,也就是智能指针,其析构函数自动对其所指对象调用delete. 以对象管理资源的两个想法:获得资源后立刻放进管理对象内:管理对象运用析构函数确保资源被释放. 若通过copy构造函数或copy assignment操作符复制它们,它们会变成null,而复制所得的指针将取得资源的…
(一) 在一项条款说法auto_ptr和tr1::share_ptr适合heap-based资源.然而,并非所有的资源都heap-based的.换句话说不tr1::shared_ptr 和 auto_ptr 总是适合作为资源管理器.管理类型. 如果Mutex类型通过lock和unlock两组函数进行相互排斥器的锁定和解锁,可能我们希望和auto_ptr一样的行为.在某个智能类型析构时主动调用unlock进行解锁. 比方以下的代码: void lock(Mutex* pm); void unloc…
1. 自己实现一个资源管理类 Item 13中介绍了 “资源获取之时也是初始化之时(RAII)”的概念,这个概念被当作资源管理类的“脊柱“,也描述了auto_ptr和tr1::shared_ptr是如何用堆资源来表现这个概念的.然而并不是所有资源都是在堆上创建的,对于这种资源,像auto_ptr和tr1::shared_ptr这样的智能指针就不适合当作资源句柄(handle)来使用了.你会发现你时不时的就会需要创建自己的资源管理类. 举个例子,假设你正在使用C API来操纵Mutex类型的互斥信…
1.为什么需要访问资源管理类中的原生资源  资源管理类是很奇妙的.它们是防止资源泄漏的堡垒,没有资源泄漏发生是设计良好的系统的一个基本特征.在一个完美的世界中,你需要依赖这样的类来同资源进行交互,绝不要直接访问原生(raw)资源而玷污你的双手.但是世界不是完美的,许多API会直接引用资源,所以除非你放弃使用这样的API(这是不实际的想法),你将会绕开资源管理类而时不时的处理原生资源. 2. 如何获取原生资源——通过显示转换和隐式转换 2.1 一个例子 举个例子,Item 13中介绍了使用像aut…
条款13:以对象来管理资源 在C++中我们经常会涉及到资源的申请与申请,一般都是由关键字new 和 delete来操作的,两者都是成对存在的,缺一不可,否则会出现意想不到的问题,例如: class Investment{.....}; Investment* pinv = createInvestment(); 我们在使用完后要动态的释放掉pinv所指向的资源,例如在下面的函数中做了调用: void f(){ Investment* pinv = createInvestment(); ...…
资源:动态分配的内存.文件描写叙述器.相互排斥锁.图形界面中的字型与笔刷.数据库连接以及网络sockets等,不管哪一种资源,重要的是,当你不再使用它时,必须将它还给系统. 条款13:以对象管理资源 当我们向系统申请资源后,一定要记得释放,不然就easy发生内存泄漏.可是意识到这样一件事并非非常easy,比方我们是通过一个函数来动态分配内存并返回一个指针. Investment* ceateInvestment();// 返回指针,指向动态分配对象 void f() { Investment*…
条款13 : 以对象管理资源 假设有如下代码: Investment* createInvestment(); //返回指针,指向Investment继承体系内的动态分配对象,调用者有责任删除它 void func() { Investment* pInv = createInvestment(); //调用factory函数 ..... delete pInv; //释放pInv所指对象 } 上述代码可能出现如下问题导致无法删除pInv指针所指对象,出现资源泄露. (1)“.....”区域内一…
参考:http://www.cnblogs.com/ronny/p/3745098.html 资源:动态分配的内存.文件描述器.互斥锁.图形界面中的字型与笔刷.数据库连接以及网络sockets等,       无论哪一种资源,重要的是,当你不再使用它时,必须将它还给系统.       条款13:以对象管理资源 当我们向系统申请资源后,一定要记得释放,不然就容易发生内存泄漏,但是意识到这样一件事并不是很容易 解决方法是我们把指针放在一个资源管理的类里,让类对象在生命结束的时候,会自动调用析构函数,…
C++程序中最常用的资源包括动态分配的内存,文件描述器,互斥锁,数据库连接,网络socket等等.不论哪种资源,重要的是,当你不再使用他时,必须将他归还给系统. 一个很好的做法是以对象管理资源.把资源放进对象内,我们便可依赖C++的析构函数自动调用机制确保资源被释放,这样便不会发生资源泄露的问题.一个实现的方法是,以智能指针封装资源,由于atuo_ptr缺陷太多,已经基本被废弃,建议使用shared_ptr.下面看一个使用shared_ptr的具体实现 void f() { shared_ptr…
1.在资源管理类中提供对原始资源的访问     前几个条款很棒,它们是对抗资源泄露的壁垒,但很多APIs直接指向 资源,这个时候,我们需要直接访问原始资源.     这里,有两种方法解决上述问题,我们可将RAII对象转换为原始资源.通过 显式转换与隐式转换.     通常,tr1:: shared_ptr 和 auto_ptr 都提供一个get成员函数,用来执行显式转换,也就是返回智能指针内部的原始指针的复件.因为它也重载了指针取值操作符* –>.当然也可以通过隐式转换为底部原始指针.     …
三.资源管理       资源就是一旦你使用了它,将来不用的时候必须归还系统.C++中最常用的资源就是动态内存分配.其实,资源还有 文件描述符.互斥器.图形界面中的字形.画刷.数据库连接.socket等. 1.        以对象管理资源       void f() {     investment *plv = createInvestment();     //这里存在很多不定因素,可能造成下面语句无法执行,这就存在资源泄露的可能.     delete plv; }      这里我们…
C++中的资源管理非常重要,在将资源加载到内存后,便可以使用资源了,当我们不再需要资源时,我们要保证其正确的释放,才能将其占用的内存空间归还给操作系统,不正确的释放很容易造成内存泄漏.本章以资源管理类为基础,提出了以下几条准则,这章内容比较简单,大概总结一下: 13. 以对象管理资源 绝大多数资源都是动态分配于堆内存之中,然后被用于某个局部范围区域内.这类资源应该在控制流离开该区域时被释放,或者全局资源在退出main函数时也应该释放.通常我们用new创建一个堆对象,最在使用完对象后用delete…
APIs往往要求访问原始资源(raw resources),所以每一个RAII class应该提供一个“取得其所管理之资源”的办法. 对原始资源的访问可能经由显示转换(.get()成员函数或者指针取值操作符->,*)或隐式转换(提供隐式转换函数).一般而言显示转换比较安全,但隐式转换对客户比较方便.…
复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为. 普遍而常见的RAII class copying行为是:抑制copying(使用私有继承Uncopyable).施行引用计数法(reference counting)(即std::tr1::shared_ptr,可以自己指定删除器).不过其他行为也都可能被实现.…
class A { private: int *p; void lock(){ cout << p << "is lock" << endl; } void unlock(){ cout << p << "is non-lock" << endl; } public: A(int* a) :p(a){ lock(); } ~A(){ unlock(); } }; int main() { int…
  我们知道在C#语言中创建一个类型的实例前,就应该初始化该类型的所有静态成员变量.C#语言为我们提供了静态初始化器和静态构造函数.其中,静态构造函数是一个特殊的构造函数,将在其他所有方法执行前以及变量或属性被第一次访问之前将自动调用静态构造函数,且仅执行一次.我们可以通过使用静态构造函数来初始化静态变量.实现单例模式或者执行类在可用之前的所有操作.但是不能够使用实例构造函数专门的私有函数或者其他什么方式来初始化静态变量. 静态类成员变量也有和实例成员类似的初始化器语法,如果只是需要为某个静态成…
以书上的代码为例 processWidget(shared_ptr<Widget>(new Widget), priority()) 虽然使用了智能指针来管理资源但是,由于参数值计算顺序的不确定性,new智能并不一定立刻在priority之前初始化了智能指针,这样如果priority抛出异常,资源就泄露了...…
我看的书是<Effective C#中文版——改善C#程序的50种方法>,Bill Wagner著,李建忠译.书比较老了,04年写的,主要针对C#1.0,但我相信其中的观点现在仍有价值.(平心而论,和Effective C++有差距,毕竟该书成书时对C#的研究不过几年.) 下面是对这本书条款内容的一些归纳和个人理解,由于我比较熟悉C++,因此也会有也一些C++的对比. 第一章 C#语言元素 条款1:使用属性代替可访问的数据成员 1. 属性具有数据成员的访问语法,这是最易于使用的语法. 2. 属…