条款 01:视 C++ 为一个语言联邦
笔记:
- C++ 是个多重范型编程语言,同时支持过程形式、面向对象形式、函数形式、泛型形式、元编程形式。
-
-
C++ 包含四种次语言:
-
- C ( C++ 以 C 为基础,但 C 有局限性:没有模板,没有异常、没有重载…… )
- Object-Oriented C++ ( C++ 支持面向对象,实现了封装、继承、多态、虚函数…… )
- Template C++ ( 模板编程,C++ 泛型编程的一部分 )
- STL ( 通用标准模板库,实现了一些可以直接拿来用的容器、迭代器、算法、函数对象,STL 有自己的规约 )
-
- 对内置类型 ( C-like ) pass-by-value 比 pass-by-reference 高效,对于自定义类型 ( 类、结构体 ) pass-by-reference-to-const 往往更好。
- STL 中迭代器和函数对象都是在 C 指针之上塑造出来的,因此旧式的 C pass-by-value 再次适用。
请记住:
- C++ 高效编程守则视状况而变化,取决于你使用 C++ 的哪一部分。
条款 02:尽量以 const, enum, inline 替换 #define
笔记:
-
-
不要用宏定义语言常量,如:
-
#define ASPECT_RATIO 1.63
- 一旦你运用此常量但是获得一个编译错误信息时,会提示你 1.63 而不是 ASPECT_RATIO,傻傻分不清楚,不知 1.63 从何而来,那么追踪这个错误数字将会浪费大量时间。解决方法是使用 const 替换上述宏:
-
const double AspectRatio = 1.653 // 宏通常全大写,这里改变写法
-
-
-
以常量替换 #define 时有两种特殊情况
-
-
-
定义常量指针(常量指针指向的值不可改,指针常量指针不可改)
- 由于常量定义式一般在头文件里面,所以不光指针所指物为 const,还有必要将指针声明为 const(以免改动)
- 例如定义一个常量的 char*-based 字符串,必须写 const 两次:
-
const char* const authorName = "Scott Meyers";
- C++ 建议用 string 对象替代 char*-based 合宜,所以这样定义往往更好些:
-
const std::string authorName("Scott Meyers");
-
-
class 专属常量
- 为了将常量作用于限制在 class 内,必须让它成为 class 的一个成员
- 为了确保常量只有一个实体,必须让它成为一个 static 成员
-
class GamePlayer { private: static const int NumTurns = 5; int socres[NumTurns]; ... };
- 如果编译器不支持在 class 内赋值,可以将初值放在定义式:
-
class CostEstimate { private: static const double FudgeFactor; // static class 常量声明位于头文件内 ... }; const double CostEstimate::FudgeFactor = 1.35; // static class 常量定义位于实现文件内
- 如果 class 编译期间需要常量有确切值,可以用枚举值:
-
class CostEstimate { private: enum { NumTurns = 5 }; // "the enum hack" —— 令 NumTurns 成为 5 的一个记号名称 int scores[NumTurns]; // 这样给数组指定大小就没问题了 ... };
-
-
- #defines 不重视作用域,一旦宏被定义,那么其后的编译过程都有效。不能在 class 内部通过 #defines 定义专属常量,也不能提供任何封装性,而 const 成员变量是可以被封装的,所谓的 private protect 。
-
-
不要写类似函数的宏,有太多缺点,光是想到他们就让人痛苦不堪
-
#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b)) int a = 5, b = 0; CALL_WITH_MAX(++a, b); // a 被累加两次 CALL_WITH_MAX(++a, b + 10); // a 被累加一次
- 不要为这种无聊的事情烦恼,使用 template inline 函数既能带来效率又能给你安全性!
-
template<typename T>; inline void callWithMax(const T& a, const T& b) { f(a > b ? a : b); }
-
请记住:
- 对于单纯常量,最好以 const 对象或 enums 替换 #defines
- 对于形似函数的宏 ( macros ) , 最好改用 inline 函数替换 #defines