[Effective C++ --013]以对象管理资源
这一节基本讲述的是将资源放进管理对象,防止忘记释放资源。
1.一般New和Delete使用场景
void fun() {
SimpleClass* pSimpleClass1 = new SimpleClass;
.... // 如果这中间发生异常返回,则delete pSimpleClass1将不会被执行,造成内存泄漏
delete pSimpleClass1;
SimpleClass* pSimpleClass2 = createSimpleClass();
.... // 如果这中间发生异常返回,则delete pSimpleClass1将不会被执行,造成内存泄漏
delete pSimpleClass2;
}
即使通过严守规约使“...”没有会产生异常的代码,或者对异常的情况进行特殊处理。但是随着代码的不断维护,“...”很容易就会被加入会产生异常的代码,而delete的处理也就很容易被忽略了。
针对这样的情况,条款13要求,以对象管理资源。
2.如果不清楚资源将以什么方式来释放,我们可以使用自动指针auto_ptr与shared_ptr来实现:
auto_ptr使用场景
void funAutoPtr() {
std::auto_ptr<SimpleClass> pSimpleClass1(new SimpleClass);
....
std::auto_ptr<SimpleClass> pSimpleClass2(createSimpleClass());
....
}
shared_ptr使用场景
void funAutoPtr_shared() {
std::tr1::shared_ptr<SimpleClass> pSimpleClass1(new SimpleClass);
....
std::tr1::shared_ptr<SimpleClass> pSimpleClass2(createSimpleClass());
....
}
两者的区别:
auto_ptr:如通过拷贝构造函数湖泊拷贝赋值操作符赋值他们,自动指针将变成NULL,而复制所得的指针将取得指针指向的资源唯一拥有权
shared_ptr:拷贝完后两者都指向同一资源
auto_ptr复制行为场景
void funAutoPtrCopy() {
std::auto_ptr<SimpleClass> pSimpleClass1(createSimpleClass); //pSimpleClass1指向createSimpleClass返回的实例
std::auto_ptr<SimpleClass> pSimpleClass2(pSimpleClass1); //现在pSimpleClass2指向实例,而pSimpleClass1被设为null
pSimpleClass1 = pSimpleClass2; //现在pSimpleClass1指向实例,而pSimpleClass2被设为null
}
shared_ptr复制行为场景
void funAutoPtrCopy_shared() {
std::tr1::shared_ptr<SimpleClass> pSimpleClass1(createSimpleClass); //pSimpleClass1指向createSimpleClass返回的实例
std::tr1::shared_ptr<SimpleClass> pSimpleClass2(pSimpleClass1); //现在pSimpleClass1和pSimpleClass2同时指向实例
pSimpleClass1 = pSimpleClass2; //同上,无任何改变
}
3.自动指针不智能的时候
auto_ptr针对Array使用的错误场景
void funAutoPtrError() {
std::auto_ptr<std::string> pStringArray(new std::string[]);
....
std::auto_ptr<int> pIntArray(new int[]);
....
}
shared_ptr针对Array使用的错误场景
void funAutoPtrError_shared() {
std::tr1::shared_ptr<std::string> pStringArray(new std::string[]);
....
std::tr1::shared_ptr<int> pIntArray(new int[]);
....
}
这是为什么呢?
因为auto_ptr与shared_ptr两者在析构函数内做的都是delete而不是delete[]操作。这就意味着动态分配得到的数组是不能完全得到释放的。
◆总结
1.为防止资源泄露,请使用RAII(Resourse Acquisition Is Initialization)"资源取得时机便是初始化时机"对象,它们在构造函数中获得资源并在析构函数中释放资源。
2.两个常用的RAII class分别是shared_ptr和auto_ptr,前者通常是较佳选择,因为其copy行为比较直观。若选择auto_ptr,复制动作会使它(被复制物)指向NULL。
[Effective C++ --013]以对象管理资源的更多相关文章
- Effective C++(13) 用对象管理资源
问题聚焦: 从这条准则开始,都是关于资源管理的. 资源,一旦用了它,将来必须还给系统. 本条准则,基于对象的资源管理办法,建立在C++的构造函数,析构函数和拷贝函数(拷贝构造函数和重载赋值操作符)的基 ...
- Effective C++ ----以对象管理资源
以对象管理资源 通过对象的析构函数的自动调用来自动释放资源 第一部分:几种典型的以对象管理资源的例子 1. STL::auto_ptr 获取资源后立刻放入资源管理对象 std::auto_ptr< ...
- 《Effective C++》学习笔记条款13 以对象管理资源
条款 13 :以对象管理资源 例: voidf() { Investment *pInv = createInvestment(); ... ...
- Effective C++ 条款13/14 以对象管理资源 || 在资源管理类中小心拷贝行为
三.资源管理 资源就是一旦你使用了它,将来不用的时候必须归还系统.C++中最常用的资源就是动态内存分配.其实,资源还有 文件描述符.互斥器.图形界面中的字形.画刷.数据库连接.socket ...
- effective C++ 读书笔记 条款14 以对象管理资源
如果我们使用一个投资行为的程序库: #include "stdafx.h" #include <iostream> #include <memory> us ...
- 以对象管理资源——C++智能指针auto_ptr简介
auto_ptr是C++标准库提供的类模板,它可以帮助程序员自动管理用new表达式动态分配的单个对象.auto_ptr对象被初始化为指向由new表达式创建的对象,当auto_ptr对象的生命期结束时, ...
- EC笔记:第三部分:13、以对象管理资源
C++相比Java等含有gc的语言来说,内存管理方面(也包括资源管理)比较令人头疼.一些初级程序员,甚至是一些经验丰富的老程序员,也会经常在资源管理上犯错.这时候就需要一个能够自动管理资源的东西(gc ...
- Effective C++ -----条款13:以对象管理资源
为防止资源泄漏,请使用RAII(Resource Acquisiton Is Initialization) 对象,它们在构造函数中获得资源并在析构函数中释放资源. 两个常被使用的RAII class ...
- C++以对象管理资源
先看下面一段代码: class Node {}; Node* CreateNode() { } void Solve() { Node *p=CreateNode(); //调用CreateNode函 ...
随机推荐
- 【 D3.js 高级系列 — 2.0 】 捆图
捆图(Bundle)是 D3 中比较奇特的一个布局,只有两个函数,而且需要与其它布局配合使用.本文讲述捆图的制作方法. 有关捆图的例子极少,很容易找到的是:http://bl.ocks.org/mbo ...
- jquery的API查看 / prepend、prependTo、append、appendTo的用法
理解jquery设计思想 记住大部分jquery API的使用 英文:http://api.jquery.com/ 中文: http://www.css88.com/jqapi-1.9/ http:/ ...
- EntityFramework版本下载和更新
安装指定版本的Package(例如:EntityFramework 5.0): PM> Install-Package EntityFramework -ProjectName MusicSto ...
- ADO.NET - 全面梳理
转自:http://www.cnblogs.com/yangcaogui/archive/2012/06/09/2537086.html 目录: 简单的介绍下ADO.NET SqlConnection ...
- xmlns 属性
xmlns 属性 xmlns 属性可以在文档中定义一个或多个可供选择的命名空间.该属性可以放置在文档内任何元素的开始标签中.该属性的值类似于 URL,它定义了一个命名空间,浏览器会将此命名空间用于该属 ...
- HDU 1560 DNA sequence DFS
题意:找到一个最短的串,使得所有给出的串是它的子序列,输出最短的串的长度,然后发现这个串最长是40 分析:从所给串的最长长度开始枚举,然后对于每个长度,暴力深搜,枚举当前位是哪一个字母,注意剪枝 注: ...
- VirtualBox故障一例
早上的测试环境,估计是任务太重了吧,在点击VirtualBox的快速休眠后,就没有响应了,查看日志,内容都是: aComponent={Console} aText={The virtual mach ...
- [转载]su认证失败
Ubuntu 安装后,root用户默认是被锁定了的,不允许登录,也不允许 "su" 到 root.有人说这是个不好的实践,特别是对于服务器来说.我觉得对于桌面用户来说,这样安全性更 ...
- SimpleHttpServer的学习之UML
如何分析一个稍微大点的源码呢? 静态分析 除了看代码,就是 uml图,UML虽然在书本类与类之间的关系很复杂,可能要一本书,但是最核心的其实很简单: (1)继承 extends (2)实现接口 imp ...
- JDK1.5新特性(五)……Typesafe Enums
援引 Typesafe Enums - This flexible object-oriented enumerated type facility allows you to create enum ...