条款01:四个次语言:C、Object-Oriented C++、Template C++(泛型和模板元编程)、STL
条款02:用inline、enum、const代替#define
#define定义的宏,复杂起来,就会很难理解。
(1)对于单纯常量,最好以const对象代替#defines。
class CostEstimate{
private:
static const double FudgeFactor; //常量声名,放在头文件
...
};
const double CostEstimate::FudgeFactor=1.35; //常量定义,放在实现文件内
(2)“the enum hack”补偿做法,解决编译期间class需要一个class常量
class GamePlayer{
private:
enum{ NumTurns=5 }; //使NumTurns成为5的记号
int scores[NumTurns];
...
};
(3)对于形似函数的宏,用inline函数替代#define。
条款03:尽可能使用const
(1)不需要进行改变的数据加上const前缀。包括指针、迭代器、指针迭代器及reference指代的对象、函数参数、返回类型、lacal变量、成员函数前。
(2)指针的const前缀有两种形式,const放在*左边表示数据不变,放右边表示指针地址不变。
(3)迭代器由指针塑模。区分const迭代器的两种情况:
const std::vector<int>::iterator iter=vec.begin(); // T* const 不可改变指针值
std::vector<int>::const_iterator cIter=vec.begin(); //const T* 不可改变对象值
(4)不改变的函数返回值加const。如重载运算符函数,可让“a*b==c”写成“a*b=c”的打字错误在编译时报错。
(5)返回不需要修改的成员数据的成员函数需要加上const标记。编译器强制实施bitwise constness,但编写程序时应该使用“概念上的常量性”。既编译器认为const成员函数不可以更改对象内任何non-static成员变量。
(6)在const和成non-const成员函数中避免重复。当const和non-const成员函数有着实质等价的实现时,令non-cosnt版本调用const版本可避免代码重复。
class TextBlock{
public:
...
const char& operator[](std::size_t position) const
{
...
... //这些是相同操作
...
return text[position];
}
char& operation[](std::sizr_t position)
{
return const_cast<char&> //转型二:为const op[]的返回值去掉const
(ststic_cast<const TextBlock>(*this) //转型一:为*this加上const
[position]) ;
}
...
};
条款04:使用对象前确保初始化。
(1)为内置型对象进行手工初始化,因为C++不保证初始化它们。
(2)确保每一个构造函数都将每一个成员初始化。构建函数最好使用成员初值列(member initialization list),而不要在构建函数本体内使用赋值操作。初值列列出的成员变量,其排列次序应该和它们在class中的声明次序相同。
(3)C++对“定义于不同的编译单元内的non-local static对象”的初始化相对次序并无明确定义,为免除“跨编译单元之初始化次序”问题,请以local static对象替换non-local static对象。这种reference-returning函数结构简单:第一行定义并初始化一个local对象,第二行返回这个对象。
class FileSystem { ... };
FileSystem& tfs() //这个函数用来替换tfs对象
{
static FileSystem fs; //定义并初始化local static对象
return fs;
}
class Directory { ... };
Directory::Directory(params)
{
...
std::size_t disks=tfs().numDisks(); //使用tfs对象
...
}
Directory& tempDir() //这个函数用来替换td对象
{
static Directory td; //定义并初始化local static对象
return td;
}