就学习难度而言,C++是一门臭名昭著的编程语言。《Effective C++》总结了 55 条 C++(98/03)的开发准则,供开发者学习参考。本篇笔记包含 Term 01~04,我也依据 Modern C++ 的改变,对其中某些细节进行了修订。
Term 01:视 C++ 为一个语言联邦
这一点说起来容易(做起来难)。简单讲,C++ 的语言设计其实有四个部分 :(兼容)C、面向对象、泛型和模板、STL,这四个部分相互关联却又在设计思想上相对独立。每一个部分都会有一些不同的准则,在 C 中的常用思路不一定适合在泛型和模板中使用。
一般来说,泛型和模板这一部分是 C++ 程序员最薄弱的,需要特别注意。
Term 02:尽量以 const, enum, inline 替换 #define
- 对于常量,使用 const 或者 enum hack 代替
- 对于形似函数的宏定义,使用 inline 函数代替(可能会用到模板)
// enum hack 的例子:
class Game {
private:
static const int GameTurn = 10;
int scores[GameTurn];
}; //不支持类内初始化的编译器报错
class GamePlayer{
private:
enum {NumTurns = 5};
int scores[NumTurns];
}; //不支持类内初始化的编译器也能编译通过
Term 03:尽可能使用 const
- const 和指针:记住
const
出现在*
左边,表示被指物是常量;如果出现在*
右边,表示指针自身是常量;如果出现在*
两边,表示被指物和指针都是常量 - STL 的迭代器可以视为指针,
const std::vector<int>::iterator iter
效果等同于T* const
,std::vector<int>::const_iterator cIter
效果等同于const T*
- 设置函数返回对象为 const 可以排除一些不必要的安全隐患
- 类的成员函数可以通过(函数名之后,函数体之前的那个)
const
重载,分别针对 const/non-const 对象 - bitwise const 和 logical const 的区别,通过
mutable
实现 logical const - 当成员函数的 const/non-const 版本有同样的实现时,可以将实现代码写在 const 版本中,而在 non-const 版本中调用即可,但是需要注意转换类型,并且一定要小心,避免安全隐患。
class TextBlock {
public:
const char& operator[](std::size_t position) const { return text[position]; }
char& operator[](std::size_t position) {
return const_cast<char&>(static_cast<const TextBlock&>(*this)[position]);
}
// ......
};
Term 04:确定对象被使用前已被初始化
- 手动初始化内置型对象,比如
int i = 0;
- 构造函数使用成员初值表进行初始化
- 为免除“跨编译单元初始化顺序不确定”问题,使用 local static 对象替换 static 对象