Effective C++读书笔记

Effective C++可谓是学习C++的必读经典书目,Effective C++: 55 Specific Ways to Improve Your Programs and Designs, Third Edition为其作者Scott Douglas Meyers于2005年对1991年完成初版, 1997年修订第二版的本书的再次改进与补充.

Accustoming Yourself to C++: 让自己习惯C++

“习惯”可能代表着了解C++的基本特性, 用C++的风格而不是别的来编写C++程序.

View C++ as a federation of languages: 把C++视为多种子语言组成的联盟

Scott Meyers在书中表示他认为C++由四种子语言组成, 分别为C, 面向对象的C++, 模板C++和STL C++. 或许随着时间的流逝, 语言的发展, 这种分类已经不再完全和恰当, 但毫无疑问C++仍然是一种多范式的编程语言, 在其不同的编程范式中应用的策略将会有所不同.

Prefer consts, enums, and inlines to #defines: 尽量使用const常量, enum枚举类型和inline内联函数来替代宏定义

总而言之, 尽可能减轻预处理器的工作量, 将工作交给编译器来处理. 宏定义的问题主要在于其字符串替换的实现方式导致了可能出现通常是输入相关的多次执行等副作用, 调试更加困难, 并且不受到任何作用域的控制, 可能导致莫名其妙的编译错误. 相对的, 使用const常量定义”具名常量”(可读的常量, 而不是magic number), 保证在多处使用相同的值并避免同一常量的多个拷贝; 使用inline内联函数来实现”无需函数调用的函数”均达到了对应情形下宏定义的目标, 且它们在其他方面将会像是普通的变量/函数一样的工作和被对待(例如类型检查, 例如按值/按引用传递, 作用域), 使得这些依靠编译器的方式相比宏定义更加安全.
有些编译器可能会在有些情况下拒绝编译使用const常量作为定义的数组长度的代码, 书中介绍了一种被称为enum hack的技巧:

1
2
enum {ARRAY_SIZE = 810};
int arr[ARRAY_SIZE];

来绕过这种限制.

Use const whenever possible: 尽可能的使用const

const限定的变量被标明了不会被修改, 编译器会协助确保这一点; const限定的成员函数声明了不会修改类的成员变量, 同样由编译器确保这种声明将会被履行. 因此尽可能的使用const限定不应被修改的变量和不应修改成员的函数, 可以避免错误的操作. 然而编译器不是万能的, 对于仅仅保证了逐位意义上的常量性: 在const成员函数中, 对于类的任何一位的修改是被禁止的. 但实际上的常量性可能不止在于逐位意义, 像是这样的代码就会通过编译:

1
2
3
4
5
6
7
8
class Foo{
private:
char* str;
public:
Foo(){str = new char[42];}
void bar()const{str[5] = 's';}
~Foo(){delete[] str;}
};

void Foo::bar()const是一个保证了逐位常量性的函数, 但很可能没有保证逻辑常量性. 类似情况下逻辑常量性的保证上编译器可能鲜有贡献. 同时, 编译器还可能阻止const成员函数修改一些对外不可见的辅助成员, 可以用mutable关键字解除这种限制.

⬆︎TOP