[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函 ...
随机推荐
- I.MX6 bq27441 driver hacking
/************************************************************************* * I.MX6 bq27441 driver ha ...
- ShopNc商城修改详情
1. 修改400电话.(400.png) a.位置:在页面顶部搜索的后面. b.修改文件: t/layout/home_layout.php 增标签 <img border=0 src=&quo ...
- MFC中状态栏显示鼠标坐标位置
原文:MFC中状态栏显示鼠标坐标位置,蝈蝈 1,利用MFC向导创建一个应用工程ewq. 2,打开ResourceView,右击Menu菜单,插入Menu,在空白处双击,Caption中填入Point. ...
- HDU 5690 All X 暴力循环节
分析:暴力找循环节就好了 #include <iostream> #include <cstdio> #include <cstdlib> #include < ...
- Educational Codeforces Round 3 E (609E) Minimum spanning tree for each edge
题意:一个无向图联通中,求包含每条边的最小生成树的值(无自环,无重边) 分析:求出这个图的最小生成树,用最小生成树上的边建图 对于每条边,不外乎两种情况 1:该边就是最小生成树上的边,那么答案显然 2 ...
- Webdriver API (二)
(转载) 1.3 打开测试页面 对页面对测试,首先要打开被测试页面的地址(如:http://www.google.com),web driver 提供的get方法可以打开一个页面: // And no ...
- 谈谈Nginx有哪些特点
1.热部署 我个人觉得这个很不错.在master管理进程与worker工作进程的分离设计,使的Nginx具有热部署的功能,那么在7×24小时不间断服务的前提下,升级Nginx的可执行文件 ...
- 全栈式框架的选择:MEAN or MEANS?
说明:个人博客地址为edwardesire.com,欢迎前来品尝.本博客作为备份和引流 这两个月一直在进行sails后端开发,其中遇到的问题不断.放在研究用户访问控制矸例程上的时间太多,最后也没用弄出 ...
- SAP:建表时如果有QUAN、CURR类型的字段不能激活的问题
建表时如有一个QUAN类型的字段,那么就要给字段设置Reference field,参考的字段的Data Type要是UNIT, 并设置对应的Reference table,也就是参考字段所在的tab ...
- Excel数据导入导出
1.将sql数据库表中的数据导入到Excel表格里: 方法一.使用StreamWrite对象,这里要注意的是 用“\t”换列,StreamWrite对象的WriteLine方法 一行一行写入. pub ...