《effective c++》读书笔记2

条款13:以对象管理资源

使用RAII,获得资源后立刻放进管理对象,管理对象运用析构函数确保资源被释放。

为防止资源泄露,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放资源。

两个常被使用的RAII类是tr1::shared_ptr和tr1::auto_ptr。前者通常是较佳选择,因为其拷贝行为比较直观。若选择auto_ptr,复制动作会使被复制物指向null.

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

n  复制RAII对象必须一并复制它所管理的资源,所以资源拷贝行为决定RAII对象的拷贝行为。

n  普遍而常见的RAII类拷贝行为是:抑制拷贝,使用引用计数法。

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

n  APIs往往要求访问原始资源,所以每一个RAII类应该提供一个取得其所管理之资源的办法

n  对原始资源的访问可能经由显示转换或隐式转换。一般而言显式转换比较安全,但隐式转换对客户比较方便。

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

考虑下面的typedef,:

typedef std::string AddressLines[4];

由于AddressLines是个数组,如果这样使用new;

std::string *pal=new AddressLInes;

那就必须匹配数组形式的delete:

delete pal;   //未定义行为

delete []pal;  //正确

n  如果你在new表达式中使用[],必须在相应的delete表达式中也使用[]。如果你在new表达式中不使用[],一定不要在相应的delete表达式中使用[]。

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

考虑以下代码:

int priority(); //处理程序的优先级

void processWidget(std::tr1::shared_ptr<Widget>  pw,int priority);

processWidget(std::tr1::shared_ptr<Widget>(new Widget),priority());

以上代码可以通过编译,但却不是异常安全的,因为new Widget和priority()的调用顺序是不确定的。如果调用的顺序是这样的:

1.      执行new Widget

2.      调用priority

3.      调用tr1::shared_ptr构造函数

如果调用priority时出现了异常,new Widget申请的资源将会出现内存泄露。

避免上述问题的方法是分离语句:

std::tr1:shared_ptr<Widget> pw(newWidget);

processWidget(pw,priority());

这样,编译器就不能任意选择语句的执行顺序了。

n  以独立语句将newed的对象存储到智能指针内。如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄露。

条款18:让接口容易被正确使用,不易被误用

n  好的接口容易被正确使用,不容易被误用,你应该在你的所有接口中努力达成这些性质。

n  促进正确使用的办法包括接口的一致性,以及与内置类型的行为兼容。

n  阻止误用的办法包括建立新类型,限制类型上的操作,束缚对象值,以及消除客户的资源管理责任。

条款19:设计class犹如设计类型

设计优秀的calsses是一项艰巨的工作,因为设计好的types是一项艰巨的工作。好的types有自然的语法,直观的语义,以及一个或者多个高效实现品。在C++中,一个不良规划下的class定义恐怕无法达到上述任何一个目标,甚至class的成员函数的效率有可能受到他们如何被声明的影响。

条款20:宁以传递指向const的引用代替传值

考虑以下类:

classWindow

{

public:

std::string name()
const;

virtualvoid display()const;

};

classWindowWithScrollBars:public Window

{

public:

virtualvoid display()const;

};

voidprintNameAndDisplay(Window w)

{

std::cout<<w.name()<<endl;

w.display();

}

如果调用上述函数并交给它一个Window对象,在函数内调用的是Window::display,而不会调用派生类的display函数,解决上述问题的办法是:

void printNameAndDisplay(const Window&w)

{

std::cout<<w.name();

w.display();

}

传引用的方式相比于传值的方式,有两个优点,一是提高程序的执行效率二是避免了对象的分割问题。

n  尽量以传递指向常量的引用代替传值,前者通常更加高效,并可避免切割问题

n  以上规则并不适用于内置类型,以及STL的迭代器和函数对象。对它们而言,传值往往比较适当。

条款21:必须返回对象时,别妄想返回其引用

如果重载乘法运算符如下:

const Rational & operator *(constRational &lhs,const Rational &rhs)

{

Rational result(lhs.n*rhs.n,lhs.d*rhs.d);

return result;

}

这个函数返回了局部变量的引用,因而是错误的。

在看另外一个版本:

const Rational & operator *(constRational& lhs,const Rational & rhs)

{

Rational *result=newRational(lhs.n*rhs.n,lhs.d*rhs.d);

return *result;

}

这个函数完成了对象的初始化工作,但是堆上分配的内存无法释放因为会造成内存泄露问题。

必须返回一个对象时,函数的正确写法是:就让那个函数返回一个新对象。

函数可以改写如下:

inline const Rational operator *(constRational &lhs,const Rational &rhs)

{

return Rational(lhs.n*rhs.n,lhs.d*rhs.d);

}

为了获取正确的结果,必须忍受一个构造函数和析构函数的代价。

 条款22:将成员变量声明为private

n  切记将成员变量声明为private,这可赋予客户访问数据的一致性,可细微划分访问控制,允诺约束条件获得保证,并提供class作者以充分的实现弹性。

条款23:宁以non-member non-friend函数替换member函数

考虑以下类:

classWebBrower

{

public:

voidclearCache();

voidclearHistory();

voidremoveCookies();

};

如果想要连续调用三个函数,可以这样设计一个成员函数:

classWebBrowser

{

public:

voidclearEverything();  //调用上面三个函数

};

这个函数也可以使用以下的版本代替:

voidclearBrowser(WebBrowser & wb)

{

wb.clearCache();

wb.clearHisttory();

wb.removeCookies();

}

这个非成员非友元的版本要比成员函数的版本更好,因为它不能访问private成员,提供了更大的封装性。

 条款24:若所有参数皆需类型转换,请为此采用非成员函数

考虑以下类的定义:

class Rational

{

public:

constRational operator *(const Rational *rhs) const;

}

尝试如下方式调用:

result=oneHalf*2; //正确

result=2*oneHalf;  //错误

只有参数被列于参数列表中时,这个参数才是隐式类型转换的合格参与者。

n  如果想让result=2*oneHalf;也成为合法的调用,可以把operator*()函数写成非成员函数的形式。

如果需要为某个函数的所有参数进行类型转换,那么这个函数必须是个非成员函数。

条款25:考虑写出一个不抛出异常的swap函数

n  当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常

n  如果你提供一个memberswap,也该提供一个non-member swap用来调用前者,对于类也请特化std::swap

时间: 2024-11-01 20:08:40

《effective c++》读书笔记2的相关文章

你的灯还亮着吗阅读笔记之一

<你的灯亮着吗>这本书是美国著名思想家唐纳德·高斯和维拉尔德·温伯格所著的一本关于定义问题.分析问题和解决问题的书,从1982年发行第一版至今畅销不衰被奉为问题解决领域里的经典之作,全书分为6个主题,每个主题都有若干生动有趣而又有警戒意义的故事作为主线通过对实战中实际问题的解决,引出作者对于问题解决领域的重要观点,本书所提到的解决问题的方法是新颖的,然而仅凭读一本书就能够学会如何解决问题是不可能的,所以读书也不足按部就班地教我们如何解决问题,而是希望读并通过阅读概述有所思悟,最终形成自己的分析

你的灯还亮着吗阅读笔记之三

解决问题是最后一步,建立在分析问题基础上,解决问题有多条途径,如果通过各种约束条件选择最佳的途径来解决问题是需要考虑的重要因素.问题解决后要及时进行归纳和总结,形成自己的知识库.   1.当别人能够解决问题时候千万不要越俎代庖   2.如果某人能够解决该问题当他自己却不会遇到该问题时候,首要的是让他感受到该问题   3.试试换过来指责你自己-即使只有一秒钟   4.一个小小的提醒往往别复杂的解决问题方法更有效(你的灯亮着吗)   5.任何解决问题方法都不可避免有副作用-没有最好,只有更好

你的灯还亮着吗阅读笔记之二

在对问题有了相对正确的定义后,接下来就是思考和分析问题,我们要注意搞清楚“这是谁的问题”和“问题的真正根源”,当别人能够解决问题时,千万不要越俎代庖,我认为书中提出的这种思考和分析问题的方式,对于构建和谐团队关系有着很大的启示,试想当团队之间出现问题时,如果大家都能“试试换过来指责自己”,从自身找问题,相互理解,那么团队之间会是多么和谐的景象呢. 圆满地解决问题是建立在准确定义和全面深入分析问题的基础上的.如何在各种约束条件下选择最佳的途径来解决问题是需要考虑的重要因素.书中给出了很多启发性建议

《你的灯还亮着吗》读书笔记2

由于本书只有短短6章,我就每两章写一篇读书笔记  第三章的题目是:什么是真正的问题?这章中讲述了,问题的存在往往被人忽视了,书中提到问题最难以处理的部分恰恰是去意识到它们的存在.我们在工作的时候往往都发生问题替代,把所有人或者这个圈子以外的人都用自己或者圈内人来替代,这样往往就把一些存在的真正的问题给忽视了.但是我们的工作面对的通常都不是我们自己,二是大众,因此我们应该从现实中,从别人身上来找到我们自己存在的问题.  第四章的一个故事中的一句点睛的话很有特色——你的灯还亮着么?这是解觉隧道车辆开

《你的灯还亮着吗》读书笔记1

<你的灯还亮着吗>这本书,如果从代序开始算起的话,那么章柏幸的代序就已经让我从第一印象中得知了这本所要讲述的内容. 这是一本充满问题的书,同时也是一本教会大家如何解决问题的书,它会告诉我们一种思维,一种解决问题的思路,而不是某一种具体的解决问题的方法.作者的讲述能力还是很厉害的,因为他每讲的一个故事,都会吸引我从不同的角度去思索问题的所在,在前几篇的阅读中,第一个故事让我颇有感触. 第一个故事讲的事一个电梯使用的故事,当我看到电梯调度出现问题之后,我的第一反应和大多数人一样,我在努力的去试想各

《你的灯还亮着吗?》读后感(一)

经过老师的推荐,看了一本关于我们软件工程专业方面的书,书名为<你的灯还亮着吗?>中文版,看过这本书之后,借用好搜百科的一句话:“这本书为人们思考能力的提高提供了一些启迪性的帮助.全书幽默地引导读者在处理问题时首先应该识别真正的问题,然后确定问题的拥有.”<你的灯还亮着吗?>全书中间贯穿了几个故事,透过这些故事让人对“问题”以及如何探究真正的问题这个概念有了进一步的了解.这本书不愧被称为管理者必读书之一.

《你的灯还亮着吗》 阅读笔记一

你的灯还亮着吗? 作者没有按部就班的告诉我们解决问题的方法,所以我们可以通过阅读概括出自己的感悟 解决一个问题的开始是要弄清问题的来源,了解问题的本质,如何更正确的定义问题 书中说到:“问题其实就是你期望的东西跟你体验的东西之间的差别”. 我们需要搞清楚“问题是什么”,不要迫不及待地就陷入解决问题的情形中,不要把问题的解决办法误认为是问题的定义. 就像书中说到的,你也许不能肯定自己对问题的定义有了正确的解释,可是不要放弃我们追逐问题的脚步

你的灯还亮着吗?阅读笔记之三

06你的灯还亮着吗?阅读笔记之三 问题最难以处理的部分恰恰是去意识到它们的存在. 如果在你对问题的理解中,你想不出至少 3 样可能出错的东西,那么你并没有真正的理解这个问题. 每种解决方法都会带来新的问题,我们永远都不能消灭问题.问题.解决方法以及新的问题交织成一条无穷无尽的锁链.我们能期望的最好结果就是新的问题没有我们“解决了”的那个那么棘手.我们使问题变得不那么棘手,其实只是把问题放在“别人家的后院儿里”.这种技巧叫做转嫁问题.新的问题常常是在无意识的情况下产生的. 当我们把我们的设计或定义

《你的灯还亮着吗》阅读笔记1

一开始看到这本书的名字的时候,感觉这就是一本励志书,“你的灯还亮着吗”,就是在说,你还有没有在深夜里还用功,加班编程,但是在读了开头第一章的时候,发现这就是在说明告诉读者,要怎么对待问题,怎么看待问题,怎么解决问题.问题其实就是你期望的东西和你体验的东西之间的差别,大多数情况下,问题的根源在你自己身上,哪儿来回哪儿去.在这个充满问题的社会中,我们常常寻找外界给自己带来的问题,却不能注意到问题的根源常常在你自己身上.很多人都是站在自己的立场上去思考问题,自然把所有的责任都推给他人,能做到站在对方立

你的灯还亮着吗

你的灯还亮着吗?--发现问题的真正所在 序言 问题 :没人会读序言 解决办法 :把序言作为第一章 解决方法带来新的问题 :第一章很无聊 新的解决方法 :删了第一章,把第二章作为第一章 第一部分:问题是什么 ### 第一章: 一个问题 > __背景故事:__一个办公楼(雷龙大厦)的电梯不够用了.有的租户威胁说,如果不尽快改善电梯服务,他们就要退租. 通过电梯不够用的场景,引出: > * 问题是什么? > * 谁碰到了问题? > * 问题的本质是什么? 第二章:皮特发起了一个请愿 从不