Effective C++ 读书笔记 (1.让自己习惯C++)

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

将C++视为一个语言联邦,而非单一的语言,为了理解C++,必须认识四个主要的次语言:

  • C

  • Object-Oriented C++
    (相当于是面向对象的C++)

  • Templata C++
    (C++泛型编程)

  • STL

C++并不是一个带有一组守则的一体语言;它是从四个次语言组成的联邦政府,每个次语言都有自己的规约。

C++高效编程守则视状况而变化,取决与你使用C++的哪一部分

条款二 尽量以const,enum,inline 替换#define

相当于是用编译器替换预处理器

  1. 因为发生错误时,你很可能找不到宏的名称而仅仅的到他的值,因为,define在预处理器就被替换了
  2. 使用define而不加()的话,很可能发生运算符优先级相关的错误,因为define做到的只有简单的字面替换而已。

对于单纯变量,最好以const对象或enums替换#define
对于形似函数的宏(macros),最好改用inline函数替换#define

条款三 尽可能使用const

1.const 与指针
如果const关键字在星号左边,表示被指物是常量; const T* t
如果出现在星号右边,表示指针自身是常量; T* const t
如果出现在星号两边,表示被指物和指针两者都是常量;const T* const t

2. const与迭代器
const修饰的迭代器不能指向不同的东西,因为迭代器的底层是指针。

3.令函数返回一个常量值,可以降低因客户错误而造成的意外

返回const对象可以避免像 (a*b)= c 这样的情况发生

4.bitwise const和logical const

bitwise const认为,成员函数只有在不更改对象的任何成员变量时才可以说是const,也就是它不更改对象内的任何一个bit。
bitwise const正是c++对常量性的定义,因此const成员函数不能更改对象内任何non-static成员变量。
logical const认为,一个const函数可以修改它所处理的对象内的某些bits,但只能在客户侦查不出的情况下。

5.在const和non-const成员函数中避免重复
因为需要为const和non-const对象都提供一个功能相同的函数,但是很可能这两个函数只有返回类型是否有const修饰,此时为了避免代码重复带来的编译时间、维护、代码膨胀等问题,可以让non-const函数调用const函数:
Effective C++ 读书笔记 (1.让自己习惯C++)_第1张图片

从non-const转为const的做法是不合适的,因为const成员函数承诺绝不改变其对象的逻辑状态,但是non-const函数没有这个承诺,可能会改变其对象的状态。

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

编译器强制实施bitwise constness, 但你编写程序时应该使用“概念上的常量性”。

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

条款四 :确认对象被使用前已先被初始化

1.对于无任何成员的内置类型,你必须手工完成此事:Effective C++ 读书笔记 (1.让自己习惯C++)_第2张图片
2.对于内置类型以外的任何其他对象,初始化责任落在构造函数上

注意不要混淆赋值和初始化。
尽量使用初始化列表代替在构造函数体内初始化

假设某类有一个无参构造函数,可以使用无物(nothing)作为初始化实参即可。Effective C++ 读书笔记 (1.让自己习惯C++)_第3张图片
3.一定要初始化的成员变量

如果成员变量是const或references,它们就一定需要初值,不能被赋值
因此最好使用初始化列表

4.成员变量的初始化顺序
成员变量以声明顺序初始化,与初始化列表无关。

5.static成员初始化问题
所谓static 对象,其寿命从被构造出来直到程序结束为止。
函数内的static对象称为local static对象,其他的static对象称为non-local static对象。
编译单元:产出单一目标文件的那些源码(一般指一个源码文件加上其所含入的头文件)。

真正的问题:

如果某编译单元内某个non-local static 对象的初始化动作使用了另一编译单元内某个non-local
static对象,它所用到的这个对象可能尚未被初始化,因为C++对“定义于不同编译单元内的non-local static”
对象的初始化次序并无明确意义。

解决办法:

将每个non-local static
对象搬到自己的专属函数内。这些函数返回一个reference指向它所包含的对象。然后用户直接调用这些函数,而不直接指涉这些对象

换句话说,non-local static对象被local static对象替换了。
这是单例模式的一个常见实现手法。
这个解决办法的基础在于,C++保证,函数内的local static对象会在“该函数被调用期间”“首次遇上该对象之定义式”时被初始化。

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

构造函数最好使用成员初值列(初始化列表),而不要在构造函数本体内使用赋值操作。初始化列表的顺序应和它们在class中的声明次序相同

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

你可能感兴趣的:(effective,c++)