改善程序与设计的55个具体做法 day6

条款13:以对象管理资源

资源,包括但不限于内存、句柄、GDI对象、数据库连接等。

内存要记得释放,句柄要记得closehandle, GDI对象要记得删除,数据库连接要记得关闭,等等等等。

以对象来管理这些资源就是利用 对象的构造和析构 特性,在构造函数中获得资源并在析构函数中释放资源。

两个智能指针auto_ptr 和 std::tr1::shared_ptr,前者同一时刻只能指向同一个资源,赋值的一方不再指向这个资源,被赋值的一方指向这个资源。在析构函数中对对象调用delete(而不是delete[])。

shared_ptr利用引用计数,多个指针可以指向同一个对象,当引用技术为0时,对对象调用delete(而不是delete[])。

条款14:在资源管理类中小心copying行为

这个比较好理解,管理资源的对象的copying行为(拷贝构造 和 operator=)一定要谨慎

a 必要的时候可以不允许其对外界有copying行为

b 对其管理的底层资源使用饮用计数机制(比如 shared_ptr)

c 复制其管理的底部资源(深拷贝)

d 转移其惯例的底部资源的拥有权(比如 auto_ptr)

条款15:在资源管理类中提供对原始资源的访问

原始资源 也就是上一条款中提到的 底部资源。

a 显式转换

Pointer Get() const;  提供get函数

b 隐式转换

operator 类型(){return m_ptr; }             提供类型转换函数

条款16:成对使用new 和 delete 时要采取相同形式

即 new - delete,  new [] - delete[]

这样做到原因是new[] 会在内存中记录个数,当delete[]的时候会去这(几)个内存单元读取该个数,然后按照该个数去释放(析构)内存。

如果是 new [] - delete,则可能会造成资源泄漏, 如果是 new - delete[] 则可能会导致未定义的问题。

条款17:以独立语句将newed 对象置于智能指针

这句话乍读有点绕口,其实代码写出来很简单。

e.g.

void Func(std::tr1::shared_ptr<CObject> ptr, int a)

调用时, Func(std::tr1::shared_ptr<CObject>(new CObject), GetA()), 由于参数的调用顺序和编译器的优化问题,可能会产生如下顺序的(伪)代码:

new CObject;

GetA();

std::tr1::shared_ptr<CObject>(指针)

当GetA的调用产生异常时,可能导致执行不到第三行,这样CObject对象就不会被释放了,从而造成内存泄漏。

所以本条款要说的是:

std::tr1::shared_ptr<CObject> ptr(new CObject);

Func(ptr, GetA);

时间: 2024-11-05 18:49:13

改善程序与设计的55个具体做法 day6的相关文章

改善程序与设计的55个具体做法 day9

条款23:宁以non-member.non-friend替换member函数 即 以非成员函数 非友元函数 替换成员函数. 直观上,面向对象应该尽可能的封装,封装数据.封装操作等等,所以这个条款可能有悖常理. 比如一个类成员函数CObj::Func(){ Dosomething(); } 该函数会调用其他成员函数做一点微小的工作,想一下把成员函数换成普通函数Func2(const CObj& obj); Func2(const CObj& obj) { obj.Dosomething();

改善程序与设计的55个具体做法 day7

条款18:让接口容易被正确使用,不易被误用 这里说的接口是广义上的接口,即包括但不限于函数接口.类接口.template接口等,每一种接口都是客户与你的代码进行交互的手段. 我们对客户的所谓“资质或水平”做出假设或要求,因此面对不同的客户,需要接口在形式上有足够的易用性以及足够的不被误用性. e.g. CDate(int year, int month, int day) 该类CDate的构造函数为三个int参数,分别代表年月日.客户在使用的时候很容易用错,比如写错顺序.写的日期不合法等,比较好

Effective C++ —— 改善程序与设计的55个具体做法(三)

条款01 : 视C++为一个语言联邦 C++ == C(C基本语法) + Object-Oriented C++(类,封装,继承,多态……) + Template C++(泛型编程) + STL(容器,迭代器,算法,函数对象) . 条款02 : 尽量以const,enum,inline 替换#define 1. #define 不被视为语言的一部分,其所定义的符号未被加入记号表(symbol table)内,宏内无法设置断点,无法被跟踪调试: 2. #define 定义形似函数的宏(而不是定义一

改善程序与设计的55个具体做法 day8

条款20:宁以pass-by-reference-to-const 替换 pass-by-value 即 以const引用 替换值传递. 采用引用传递参数时,底层往往是用指针方式实现,因此参数传递内置类型时,采用值传递方式往往效率更高. 如果函数参数是基类对象(值传递),传递实参时如果传递的是派生类对象,则可能会产生[切割现象]:而如果形参是const 基类引用,则不会有这个问题. 请记住: a 尽量以const引用 代替 值传递,通常前者效率较高,并且没有切割问题. b 以上规则并不适用于内置

改善程序与设计的55个具体做法 day4

条款12:复制对象时勿忘其每一个成分 这里的复制是拷贝构造和operator= 每一个成分有几个维度: 1.每个成员变量 这个很好理解,添加新的成员时也要记得为每个新添加的成员执行合适的复制操作 2.每个基类的成员变量 在子类中调用可以调用基类的拷贝构造函数或者operator= e.g. class CObject : public CBase {}; CObject::CObject(const CObject& obj) : CBase(obj), val(obj.val){} CObje

改善程序与设计的55个具体做法 day3

今天晚上回到小区门口,买了点冬枣,要结账的时候想起来,钥匙没带,落公司了! TNND,没办法再回趟公司,拿了钥匙,来回一个小时,汗~ 条款10:令operator=返回一个reference to *this 即赋值操作符返回引用. 原型 Object& operator=(const Object& obj) 同时,该协议还适用于所有的赋值操作. Object& operator=(int a)等形式 条款11:在operator=中处理“自我赋值” 即 1 Object&

改善程序与设计的55个具体做法 day2

条款05:了解C++默默编写并调用哪些函数 如果没有为类定义构造函数.析构函数.拷贝构造函数.重载赋值操作符,并且这些函数被需要(调用)时,编译器会为类生成默认的函数,而这些函数是public inline的. 需要主意的是带引用成员的类和带const成员的类. 带引用成员的类,如果不为其主动编写operator=,则对象之间的赋值操作是不能编译通过的: 带const成员的类,如果不为其编写operator=,则对象之间的赋值是不能通过编译的. 条款06:若不想使用编译器自动生成的函数,就该明确

改变程序与设计的55个具体做法笔记

1.让自己习惯C++ 视C++为一个语言联邦 C++高效编程守则视情况而变化,取决于你使用C++的那一部分 尽量以const.enum,inline替换#define 对于单纯常亮,最好以const对象或emuns替换#defines 对于形似函数的宏(macors),最好改用inline函数替换#defines 尽可能的使用const 将某些东西声明为const可帮助编译器侦测出错误的用法.const可被施加于任何作用域内的对象.函数参数.函数返回类型.成员函数本体 编辑器强制实施bitwis

[转]使用设计模式改善程序结构(三)

使用设计模式改善程序结构(三) 设计模式在某种程度上确实能够改善我们的程序结构,使设计具有更好的弹性.也正是由于这个原因,会导致我们可能过度的使用它.程序结构具有过度的.不必要的灵活性和程序结构没有灵活性一样都是有害的.本文将分析过度的灵活性可能造成的危害,并且结合一些实例来阐述使用设计模式改善程序结构应遵循的原则. 1. 介绍 本系列文章的前两篇主要讲述了如何使用设计模式来改善我们的程序结构,大家可以看到经过调整的代码具有了更大的弹性,更容易适应变化.读者朋友可能也具有类似的经验,通过使用设计