EffectiveCpp0x1
Effective C++
[toc]
导读
- 声明式:告诉编译器某个东西的
名称
和类型
,但是略去细节。
1 | templete<typename T> |
定义式:提供编译器对象、函数和模板等的实际代码本体。
初始化:给予对象值的过程。
copy构造与copy赋值:通过是否有新对象被定义区分。
Accustoming youself to C++
01. View C++ as a federation of languages
C++是一个多重范式语言:
- 过程形式(procedural):通过函数调用和控制流语句(如if语句和循环)来实现。
- 面向对象形式(object-oriented):支持封装、继承和多态等面向对象的特性。
- 函数形式(functional):
- 泛型形式(generic):C++通过模板支持泛型编程。模板允许你编写可以处理各种数据类型的通用代码。标准模板库(STL)中的容器和算法都是泛型的,可以与各种数据类型一起使用。
- 元编程形式(metaprogramming):C++提供了元编程的功能,其中最常见的是模板元编程。通过模板元编程,你可以在编译时生成代码,实现诸如计算、类型推导、代码生成等功能。
02. Prefer consts,enums,and inlines to #define
预处理
由于
预处理符号#
会在函数编译前进行复制和替换,如果发生错误,我们得到的信息将是1234
而不是Randolfluo
,于是你将为追踪他而浪费时间。正确的方法是以常量替换宏。
#define
不注重作用域,因此不具封装性。
1 |
|
- 宏看起来像函数,但是不会招致函数调用(function call)带来的额外开销。
1 |
|
类专属常量
- 静态成员变量的定义通常需要在类外部进行,以便为其分配存储空间。这是因为在类声明中只是声明了静态成员变量的存在,而没有分配内存。
1 |
|
请记住
- 对于单纯常量,最好以const对象或enums替换#define。
- 对于形似函数的宏(macros),最好改用inline函数替换#defines。
03. Use const whenever possible
- 令函数返回一个常量值,往往可以降低因错误而造成的意外。
1 |
|
const成员函数
- 将const实施于成员函数的目的,是为了确认该成员函数可作用于const对象。
- 通过pass by reference-to-const 传递对象,提高程序效率。
bitwise constness & logical constness
- 请看书
请记住
- 将某些东西声明为const可帮助编译器侦测出错误用法。const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
- 编译器强制实施bitwise constness,但你编写程序时应该使用“概念上的常量性”( conceptual constness)。
- 当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。
04. Make sure that objects are initialized before ther’re used.
- 永远在使用对象前先将它初始化。
member intialization list
- 如果成员变量是
const
或reference
,就要赋初值,使用成员初始化列表
。 - 类成员的初始化顺序不是按照初始化列表的顺序来的,而是按照类成员的声明顺序。
1 |
|
local static & non-local static
local static
对象即函数内部的 static 变量,适用于需要在函数调用间保持状态的情况,可以防止变量的多次初始化,且仅在声明的函数内部可见。
non-local static
即函数外部的 static 变量,适用于在文件内部共享状态的情况,可以防止变量被其他文件访问,且仅在声明的文件内部可见。Singleton
模式:将每个non-local static
对象搬到自己的专属函数内(该对象在此函数内被声明为static
[即local static
对象])。这些函数返回一个reference 指向它所含的对象。然后用户调用这些函数,而不直接指涉这些对象。换句话说,non-local static 对象被local static 对象替换了。
//TODO为什么默认构造函数比有初值的构造函数效率低
请记住
- 为内置型对象进行手工初始化,因为C++不保证初始化它们。
- 构造函数最好使用成员初值列( member initialization list),而不要在构造函数本体内使用赋值操作(asignment)。初值列列出的成员变量,其排列次序应该和它们在class中的声明次序相同。
- 为免除“跨编译单元之初始化次序”问题,请以local static 对象替换non-local static对象。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Randolfluo's blog!