//---------------------------15/04/09----------------------------

//#26   尽可能延后变量定义式的出现时间

{

/*  1:只要你定义了一个变量而其类型带有一个构造函数或析构函数,即使变量没有被使用

还是要承担构造或析构的成本。为了避免这种情况,应该尽可能延后变量定义式的出现

2:再一次重复条款4:直接给定一个初值来让对象初始化比先构造一个对象,再赋值效率要高。

3:对于循环的情况:

1>当赋值成本低于一组构造+析构成本时,可以把对象定义在循环外面。

2>反之,把对象定义在循环体内部。

3>效率相当时,应该把对象定义在循环体内部。

*/

}

//#27   尽量少做转型动作

{

/*  1:尽量使用C++的新式转型:

1>const_cast:

通常被用来讲对象的常量性去掉,它是唯一有此功能的转型操作符。

2>dynamic_cast:

执行安全向下转型,但是要耗费大量成本。

3>reinterpret_cast

参数必须是指针,只是转化类型,并不转化内部结构。

想比较于static_cast,static_cast在基类到子类转型时会计算偏移值,而

reinterpret_cast不会,所以这个转型很危险,尽量别用。

4>static_cast

除了去除const属性外,其他转型都行。

2:在类中不要对*this进行转型                                       */

class Window

{

public:

virtual
void onResize(){...}

...

};

class SpecialWindow:public Window

{

virtual
void onResize()

{

static_cast<Window>(*this).onResize();

}

};

/*    上面这样调用的是转型时产生的副本(一个derived临时对象)的
base部分的那个函数。

所以不应该这么调用,而是使用Window::onResize();

3:dynamic_cast转型太慢了,能不用就不用,可以用两个方法避免这个转型:

1>直接使用derived类型的指针

2>在基类中定义一个无操作的virtual函数。

*/

}

//#28   避免返回handles指向对象内部成分

{

/*  1:如果返回一个handles(包括指针,引用,迭代器)指向对象内的private成员变量,那么外部就可以直接

修改这个成员变量了。虽然编译没错,但是这样就没有封装性可言了。

2:这带给我们两个教训:

1>成员变量的封装性最多只等于“返回其handles”的函数的访问级别。如果这个函数是public的

那么这个成员变量就是public的。

2>如果const成员函数传出一个handle,handle所指的数据与对象自身有关"private"或"protected"

而handle又被存储在对象之外,那么这个函数的调用者可以修改上面所指的数据。这是不合理的!!!

3:解决办法:

使返回指针和引用都是const就行了。

引用方式:                                                               */

const Point& upperLeft()
const { return pData->ulhc;}

//      指针方式:

const Point * upperLeft()
const { return pData;}

/*  4:返回一个handle代表对象内部成分总是危险的,这是因为:

handle被传出去就有可能产生 handle比它所指对象生命周期更长。

也就是handle很有可能在某时刻指向不存在的资源:                                  */

GUIObject* pgo;

...

const Point* pUpperLeft = &(boundingBox(*pgo).upperLeft());

//  这里只产生了一个临时对象,所以这条语句结束后就销毁了,而pUpperLeft也指向了已经销毁的对象资源

//  所以能避免返回handlers就避免吧。

}

//#29   为“异常安全”而努力是值得的

{

/* 1:“异常安全”有两个条件:

1>不泄漏任何资源。

解决办法是使用#13的办法,用对象(智能指针)来管理资源。

2>不允许数据败坏

2:异常安全函数提供三种保证之一:

1>基本承诺:如果异常被抛出,程序内的任何事物扔然保持在有效状态下。没有任何对象或数据结构会

因此而败坏,所有对象都处于一种内部前后一致的状态。然而程序的现实状态不可预料。

2>强烈保证:如果异常被抛出,程序状态不改变。调用这样的函数可以有这样的认知:如果函数成功,

就是完全成功,如果函数失败,程序会回到“调用函数前的状态”。

3>不抛掷(nothrow)保证:承诺绝不抛出异常。

3:我们的抉择:

1>有可能的话,提供nothrow保证。

大部分情况:

2>尽可能提供强烈保证,这里有一个好策略,不要为了表示某件事将要发生而改变对象状态,除非那件

事情已经发生了。

有一个好的策略会导致强烈保证:copy and swap。要做的事情就是:

1)先为要打算修改的对象copy一个副本。

2)把要做的事情都在副本上完成。

3)交换原对象和副本。

这里swap函数必须要能保证不抛出异常。

这个策略并不能保证整个函数有强烈的异常安全性。因为:

1)除了copy and swap外,如果还调用了其他函数,那么除非其他函数提供强烈异常保证

以上保证,不然就很难让整个函数提高强烈异常保证了。

2)即使其他函数提供了强烈异常保证,情况还是没有好转,因为其中一个函数改变了程序状态后

另外一个函数抛出了异常。

还有一件事会妨碍你提供强烈异常保证--效率问题,copy and swap带来的是一个对象的复制,

有时会消耗你无法承受的时间和空间。

3>当提供强烈保证不切实际时,就必须提供基本保证。

但是有时候可能你连基本保证都无法提供,是的。

如果你调用的函数原本不提供保证,那~~除非不调用,不然就没有任何保证了。。。。。

为了别人不会遇到同样的痛苦,你必须尽可能为你的函数提供异常保证。

*/

}

effective c++ 笔记 (26-29)的更多相关文章

  1. [Effective JavaScript 笔记]第29条:避免使用非标准的栈检查属性

    许多js环境都提供检查调用栈的功能.调用栈是指当前正在执行的活动函数链.在某些旧的宿主环境中,每个arguments对象含有两个额外的属性:arguments.callee和arguments.cal ...

  2. [Effective JavaScript 笔记]第3章:使用函数--个人总结

    前言 这一章把平时会用到,但不会深究的知识点,分开细化地讲解了.里面很多内容在高3等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...

  3. Effective Java笔记一 创建和销毁对象

    Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...

  4. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  5. [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符

    “1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...

  6. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

  7. [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

    js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

  8. java effective 读书笔记

    java effective 读书笔记 []创建和销毁对象 静态工厂方法 就是“封装了底层 暴露出一个访问接口 ” 门面模式 多参数时 用构建器,就是用个内部类 再让内部类提供构造好的对象 枚举 si ...

  9. JAVA自学笔记26

    JAVA自学笔记26 1.网络编程 1)用来实现网络互联的不同计算机上运行的程序可以进行数据交换 2)网络模型一般泛指 OSI:(Open System Interconnection)开放系统互联参 ...

  10. Effective STL 笔记 -- Item 6 ~ 7: Container and Object Pointer

    Effective STL 笔记 – Item 6 ~ 7: Container and Object Pointer 中间两次笔记被删掉了,简单补一下: Item 3 中提到如果将对象直接放入容器中 ...

随机推荐

  1. 关于SQLSERVER走起公众帐号推送视频的通知

    关于SQLSERVER走起公众帐号推送视频的通知 为了SQLSERVER走起这个微博帐号和微信帐号更加多样化,内容更加丰富 也为了发挥微信.微博的媒介传播威力,在以后的微博.微信每日推送中会在适当的时 ...

  2. 如何扩展 Azure 资源组中虚拟机的 OS 驱动器

    概述 在资源组中通过从 Azure 应用商店部署映像来创建新的虚拟机 (VM) 时,默认的 OS 驱动器空间为 127 GB. 尽管可以将数据磁盘添加到 VM(数量取决于所选择的 SKU),并且我们建 ...

  3. sql server中quotename()函数的用法(转载)

    操作sql server尤其是写存储过程时,要用到各种各样的函数,今天就总结一个quotename()的用法.1.语法: quotename('character_string'[,'quote_ch ...

  4. 针对于多个inner join或者left join多条件查询的时候,各个inner join 的指向问题

    转自https://blog.csdn.net/ck457897564/article/details/52487684 先看一段代码吧: <span style="font-size ...

  5. 转:sql语句优化

    性能不理想的系统中除了一部分是因为应用程序的负载确实超过了服务器的实际处理能力外,更多的是因为系统存在大量的SQL语句需要优化. 为了获得稳定的执行性能,SQL语句越简单越好.对复杂的SQL语句,要设 ...

  6. spring-bean 版本的问题(报错:org.xml.sax.SAXParseException; lineNumber: 14; columnNumber: 75;)

    当XML中配置的xsd是4.0,而引用的包是4以下的spring-bean.jar时,当服务器能连网时没问题,不能连网时,就报以下类似错误: org.xml.sax.SAXParseException ...

  7. 移动端真机调试抓包,fiddler web debugger

    小白一枚,在公司大神指导下加之找了好多资料才勉强将fiddler的使用摸透,果然很好用. 一.设置手机 二.设置fiddler

  8. BZOJ3105:[CQOI2013]新Nim游戏(线性基,贪心)

    Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴 ...

  9. 恶意代码技术第一二部分——P201421410029

    学   号:201421410029   中国人民公安大学 Chinese people’ public security university 网络对抗技术 实验报告   实验四 恶意代码技术   ...

  10. linux问题解答

    1.Linux如何查询进程?杀死一个进程? ps命令提供进程的一次性查看(瞬时信息),结果不是动态的:top对命令实时监控 ps只是查看进程,而top还可以监视系统性能,如平均负载,cpu和内存的消耗 ...