个人读书记录,不适用教学内容。
目录
条款01:视C++为一个语言联邦
条款02:尽量以const,enum,inline替换#define
条款03:尽可能使用const
所谓的"顶层const"和"底层const"
const返回值
const成员函数
bitwise constness和logical constness
在const和non-const成员函数中避免重复
条款04:确定对象被使用前已先被初始化
不要混淆赋值(assignment)与初始化(initialization)
成员初始化顺序
不同编译单元内的non-local static对象初始化顺序
条款01:视C++为一个语言联邦
感觉没有啥好说的。
- C++是以C为基础的
- Objected-Oriented C++。C++是面向对象的语言
- Template。以泛型编程为特色
- STL。template程序库
条款02:尽量以const,enum,inline替换#define
说白了就是指出了#define宏替换的种种弊端,所有原因都指向于:
#define使用的名称可能并未进入记号表(symbol table)。(或者叫符号表)
这个原因使得在目标码(也就是代码区)生成多份代码,而const常量就不会这样。(const和#define的区别)
其他的就是尽量用inline函数替换#define定义的函数宏,因为函数用极易因少一个括号等因素而引发错误。
条款03:尽可能使用const
所谓的"顶层const"和"底层const"
第一点需要学习的就是所谓的”顶层const“和”底层const“这个东西,这个知识点在C++primer中令许多人头疼,不说人话。
而在这本书里则讲解的清晰明了:
const语法虽然变化多端,但并不莫测高深。
- 如果const出现在 * 左边,被指物是常量
- 如果const出现在 * 右边,表示指针自身是常量
- 如果const出现在 * 两边,表示被指物和指针都是常量
书中例子:
const返回值
防止出现自定义类型中重载运算符发生的错误:
而const会预防这个错误。
const成员函数
有两个作用
- 控制成员函数是否可以改动对象的成员变量
- 控制成员函数是否可以操作const对象
bitwise constness和logical constness
在const和non-const成员函数中避免重复
简单说似乎是想利用const_cast来进行代码复用。因为const和non-const版本的成员函数内容十分类似。
说实话目前还真没遇到过类似的问题。。。可能是代码量和项目经验太少了。书中的这个两次cast的做法也没有深刻体会到其意义所在,故先存疑。
条款04:确定对象被使用前已先被初始化
简单说,就是除了内置类型(比如int,char这些)其他的自定义类型都应该由我们负责的、主动的去进行初始化。
不要混淆赋值(assignment)与初始化(initialization)
原文如下,非常值得学习:
这会导致ABEntry对象带有你期望的指,但不是最佳做法。“C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前。在ABEntry构造函数内,theName,theAddress和thePhones都不是初始化,而是被赋值。初始化发生的时间更早,发生于这些成员的default函数被自动调用之时(比进入ABEntry构造函数本体的时间更早)。
基于上述原因,推荐使用成员初始化列表来进行初始化,这也是C++面试八股文中常见的知识点:
效率高的原因是:
- 之前copy的版本:先调用default构造函数,然后再赋值。所以default构造函数所作的一切都被浪费了
- 初始化列表:直接利用列表中的成员实参去直接进行copy构造。
另外注意一点,在member initialization list中,实参如果置为空,自定义类型会调用default构造函数,内置类型则可能会出现未定义的行为。
如果成员变量是const或references,就一定需要初值,不能被赋值。
综上所述:最简单的做法就是,总是使用member initialization list
成员初始化顺序
- base class早于derived class被初始化
- class的成员变量以声明顺序被初始化,即便在member initialization list它们的顺序不同
不同编译单元内的non-local static对象初始化顺序
其实一言简之,就是用单例模式来解决:
“C++对’定义不同编译单元内的non-local static对象‘的初始化顺序并无明确定义”
这一问题。
具体的内容看原书解释吧。这里不多赘述。