1. 条款2,尽量以const,enum,inline替换#defines
(1)对于单纯常量,最好以const对象或enums替换#defines:
使用常量可能比使用#define导致较小的量的码,因为预处理器“盲目地将宏名称替换为数字”可能导致目标码出现多份数字
(2)对于宏形式的函数,改为inline。
2. 条款3:尽可能使用const
(1)const char* p = greeting ; //常量指针,指向数据是常量
char* const p = greeting ; //指针常量,指针是常量,数据非常量
const char* const p = greeting //指针和数据都为常量
(2)std::vector<int> vec;
…
const std::vector<int>:: iterator iter = vec.begin(); //相当于T* const
*iter = 10 ; //可以
++iter; //错误,iter为const
std::vector<int>::const_ierator iter = vec.begin();
//相当于const T*,常量迭代器
*iter =10; //错误,*iter为const
++iter; //可以,
(3)令函数返回一个常量值,降低客户错误而造成意外,而又不至于放弃安全性和高效性。
如:
class Rational{.....};
const Rational operator*(const Rational& lhs, const Rational& rhs);
Rational a,b,c
if (a*b = c) //能够防止“没有意思的赋值动作”。
(4) const 成员函数:(在函数声明结尾加上const)
如果函数未声明const,const对象将无法调用。目的是为了确认该成员函数可作用于const对象身上。使用const成员函数两个理由:
l 可以使class接口更容易理解。
l 使“操作const对象”成为可能。比如传参中改善程序效率的一个pass by reference-to-const方式传递对象。
const成员函数不能修改对象中任何non-static成员变量的值,除非在non-static成员变量声明前添加mutable。mutable修饰的成员变量即使在const成员函数中也可以修改。
(5)当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复,移除const属性,可以通过强制类型转化const_cast来实现。
3. 条款4:确定对象使用前已被初始化。
构造函数最好使用成员初值列,不要在构造函数本体内使用赋值操作。初值列列出的成员变量,其排列次序应该和它们在声明次序相同。