Effective C++总结

来源:互联网 发布:excel2007软件 编辑:程序博客网 时间:2024/06/05 04:33

条款01:视C++为一个语言联邦

在《Effective C++》里提到对内置(C-like)类型在函数传参时pass by value比pass by reference更高效,当用OO的c++自定义类型(存在构造/析构等)pass by reference to const 更好,STL里的迭代器和函数对象是用C指针实现的,因此pass by value更好。

条款02:尽量const、enum、inline替换#define

宁可以编译器替换预处理,比如#define A 3.4,编译器一开始处理源代码的时候,会用3.4替换掉A,如果A出现错误,错误信息也许之后提到3.4而不是A。

我们无法利用#define创建一个class专属常量,因为#define并不重视作用域。一旦被定义,它就在其后的编译过程中有效(除非在某处被#undef)。

对于单纯常量,最好以const对象或enums替换#defines。

对于形似函数的宏,最好改用inline函数替换#defines。

条款03:尽可能使用const

将某些东西声明为const可帮助编译器侦测出错误用法。const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体

当const和not-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。

条款04:确定对象被使用前已先被初始化

为内置型对象进行手工初始化,因为C++不保证初始化它们。

构造函数最好使用成员初值列,而不要在构造函数本体内使用赋值操作(对象的成员变量的初始化动作发生在进人构造函数本体之前)。初始值列出的成员变量,其排列次序应该和它们在class中的声明次序相同。

为免除“跨编译单元之初始化次序”问题,请以local static对象替换non-local static对象。

条款05:了解C++默默编写并调用哪些函数

编译器可以暗自为class创建默认构造函数、拷贝构造函数、拷贝赋值函数、以及析构函数。

条款06:若不想使用编译器自动生成的函数,就该明确拒绝

为驳回编译器自动(暗自)提供的机能,可将相应的成员函数声明为private并且不予实现。

在新标准下,我们可以通过拷贝构造函数和拷贝赋值运算符定义为删除的函数来阻止拷贝。在函数的参数列表后面加上=delete。

条款07:为多态基类声明virtual析构函数

带多态性质的基函数应该声明一个虚析构函数。如果class带有任何虚函数,它就应该拥有一个virtual析构函数。

Classes的设计目的如果不是作为base classes使用,或不是为了具备多态性,就不该声明virtual析构函数。然后声明了,会额外占体积

条款08:别让异常逃离析构函数

析构函数绝对不要吐出异常。如果一个被析构函数调用的函数可能抛弃异常,析构函数应该捕捉任何异常,然后不传播或结束程序

条款09:绝不在构造和析构过程中调用virtual函数

在构造和析构期间不要调用virtual函数,因为这类调用从不下降至derived class。

条款10:令operator= 返回一个reference to *this

令赋值操作符返回一个reference·to *this。

条款11:在operator=中处理“自我赋值“

Widget& Widget::operator=(const Widget& rhs){if (this == &rhs) return *this;delete pb;pb = new Bitmap(&rhs.pb);return *this;}Widget& Widget::operator=(const Widget& rhs){Bitmap* pOrig = pb;pb = new Bitmap(*rhs.pb);delete pOrig;return *this;}
确保当对象自我赋值时operator=有良好行为。其中技术包括比较”来源对象“和”目标对象“的地址、语句顺序、以及copy-and-swap。

确定任何函数如果操作一个以上的对象,而其中多个对象时同一个对象时,其行为仍然正确。
条款12:复制对象时勿忘其每一个成分

Copying函数应该确保复制”对象内的所有成员变量“及”所有base class 成分“

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

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

条款20:宁以pass-by-reference-to-const替换pass-by-value

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

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

条款30:透彻了解inlining的里里外外

将大多数inlining限制在小型、被频繁调用的函数身上。这可使日后的调试过程和二进制升级更容易,也可使潜在的代码膨胀问题最小化,使程序的速度提升机会最大化。

条款31:将文件间的编译依存关系降低至最低

支持”编译依存性最小化“的一般构想是:相依于声明式,不要相依于定义式。

条款32:确定你的public继承塑摸出is-a关系

“public继承”意味is-a。适用于base classes 身上的每一件事情一定也使用与derived classes身上,因为每一个derived classes对象也都是一个base classe对象。

条款34:区分接口继承和实现继承

身为class设计者,有时候你会希望derived classed只继承成员函数的接口(也就是声明);有时候你又会希望derived classes同时继承函数的接口和实现,但又希望能够覆写它们所继承的实现;又有时候你希望derived classes同时继承函数的接口和实现,平且不允许覆写任何东西。

接口继承和实现继承不同。在public继承之下,derived classes总是继承base class的接口。

pure virtual 函数只具体指定接口继承。

impure virtual 函数具体指定接口继承及缺省实现继承。

non-virtual函数具体指定接口继承以及强制性实现继承。

条款37:绝不重新定义继承而来的缺省参数值

virtual函数系动态绑定,而缺省参数数值却是静态绑定

为什么这样?答案在于运行期效率。如果缺省参数值时动态绑定,编译器就必须有某种办法在运行期为virtual函数决定适当的参数缺省值。这比目前实行的“在编译期决定”的机制更慢而且更复杂。为了程序的执行速度和编译器实现上的简易度,C++做了这样的取舍,其结果就是你如今所享受的执行效率。

条款38:通过复合塑摸出has-a或“根据某物实现出”

复合的意义和public继承完全不同

在应用域,复合意味has-a(有一个)。在实现域,复合意味着根据某物实现出。

条款39:明智而审慎地使用private继承

和复合不同,private继承可以造成empty base最优化。这对致力于“对象尺寸最小化”的程序库开发者而言,可能很重要。:

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 药流只排血块不见孕囊怎么办 药流三天还有血怎么办 药流15天同房了怎么办 药流22天同房了怎么办 药流一直不排出怎么办 宝宝脸过敏红了怎么办 小孩湿疹脸上都是红红的怎么办 眼周刺痛红红的怎么办 脸敷面膜刺痛红红的怎么办 脸上有凹凸不平的坑怎么办 宝宝脸上角质层薄有红血丝怎么办 红衣军到决赛圈怎么办 宝宝湿疹留下的黑印怎么办 出牙宝宝很烦躁怎么办 法斗嘴唇破了怎么办 狗嘴巴周围红了怎么办 脸上起红包还痒怎么办 睾丸胀痛有下坠感怎么办 英语不好又不会读怎么办 七个月宝宝手上长倒刺怎么办 字母纹身纹反了怎么办 花甲生的吃了怎么办 别人告我欠他钱怎么办 实习手册没有公司的印章怎么办? 家长管的太严怎么办 对于老公沉迷于股票怎么办 月经期吃了香瓜怎么办 月经漏到内裤上怎么办 上班没时间养狗怎么办 宝宝呼吸道感染反复发烧怎么办 熬夜后头晕想吐怎么办 生气后全身无力酸痛怎么办? 久坐导致的腰疼怎么办 削土豆手变黑了怎么办 熬夜后头痛眼痛怎么办 孩子毎天通宵游戏怎么办 熬夜写作业困了怎么办 三十多岁白头发越来越多怎么办 AI界面字体太小怎么办 睡不着怎么办躺倒床上脑子混乱 作息规律不正常夜里睡不着怎么办