[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函 ...
随机推荐
- Java [leetcode 14] Longest Common Prefix
小二好久没有更新博客了,真是罪过,最近在看linux的东西导致进度耽搁了,所以今晚睡觉前怒刷一题! 问题描述: Write a function to find the longest common ...
- ORACLE DATAGURARD 折腾记二
前文再续,书接上一回,这次折腾Data Guard的一个重要目的是利用switchover实现机器的升级,怎么switchover呢?按照我的理解,Data Guard的角色切换是这样一个过程: (1 ...
- ASP.NET_验证控件(class0620)
为什么使用验证控件 当需要让用户输入数据时,用户有可能输入不符合我们程序逻辑要求的信息,所以我们要对输入进行验证. 客户端验证(用户体验,减少服务器端压力) 服务器端验证(防止恶意攻击,客户端js很容 ...
- 专门为公共部门和联邦机构所设计Microsoft Azure
微软正式发布Microsoft Azure for Government,该云平台专门为公共部门和联邦机构所设计. 在2014年三月微软联邦执行官论坛上宣布的Microsoft Azure for G ...
- Windows下ffmpeg的完美编译
纠结了好几天,终于搞定了,小结一下. 1.下载ffmpeg源码,官网 2.编译环境Msys的安装配置,http://blog.csdn.net/jszj/article/details/4028716 ...
- 【转】shell中IFS用法
http://blog.itpub.net/27181165/viewspace-775820/ 一 IFS的介绍 Shell 脚本中有个变量叫IFS(Internal Field Seprato ...
- HW5.35
import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...
- 说说QQ空间SEO
其实这个话题由来已久,已经有很多大神做到QQ空间日访问量破万,甚至更多了,卖产品卖到抽筋儿. 怎么说QQ空间SEO,其实不如说QQ空间引流更合适,因为QQ空间与QQ的特殊关系,SEO貌似不是很重要,其 ...
- Delphi监视进程并结束进程
监视进程并结束进程在很多地方都用到这里借前人的经验写了个小例子: 以QQ的进程qq.exe为例 关键代码如下: function CheckTask(ExeFileName: string): Boo ...
- (贪心5.2.6)URAL 1014 Product of Digits(利用数据有序化进行贪心选择)
/* * URAL_1014.cpp * * Created on: 2013年10月11日 * Author: Administrator */ #include <iostream> ...