条款01:视C++为一个语言联邦
C++高效编程守则视状况而变化,取决于你使用C++哪一部分。C、Object-Oriented C++、Template C++和STL。
条款02:尽量以const,enum,inline替换#define
对于单纯常量,最好以const对象或enums替换#define。
class GamePlayer
{
private:
static const int NumTurns = 5;
int scores[NumTurns];
};
对于形似函数的宏(macros),最好改用inline函数替换#define。
条款03:尽可能使用const
以星号为界,如果关键字const出现在星号左边,表示被指物是常量;如果出现在星号右边,表示指针自身是常量;如果出现在星号两边,表示被指物和指针两者都是常量。
char greeting[] = "Hello";
char *p = greeting; //non-const pointer, non-const data
//等价于 char const *p = greeting;
const char *p = greeting; //non-const pointer, const data
char *const p = greeting; //const pointer, non-const data
const char *const p = greeting; //const pointer, non-const data
两个成员函数如果只是常量性(constness)不同,可以被重载。
class TextBlock
{
public:
...
const char& operator[](std::size_t position) const //operator[] for const 对象
{return text[position];}
char& operator[](std::size_t position) //operator[] for non-const对象
{return text[position];}
private:
std::string text;
};
条款04:确定对象被使用前已先被初始化
为内置型对象进行手工初始化,因为C++不保证初始化它们。
int a = 5;
构造函数最好使用成员初始化列表,而不要在构造函数本体内使用幅值操作。初始化列表列出的成员变量,其排列顺序应该和它们在class中的声明顺序相同。
ABEntry::ABEntry()
:theName(),
theAddress(),
thePhones().
numTimesConsulted(0)
{ }
为了免除“跨编译单元之初始化顺序”问题,请以local static对象替换non-local static对象。
//FileSystem.h
class FileSystem
{
public:
...
std::size_t numDisks() const;
...
};
extern FileSystem tfs;
//Directory.h
class Directory
{
public:
Directory(paras);
...
};
Directory::Directory(params)
{
...
std::size_t disks = tfs.numDisks();
...
}
C++对“定义于不同的编译单元内的non-local static对象”的初始化相对顺序并没有明确定义。可以用local static对象替换non-local static对象来解决。
//FileSystem.h
class FileSystem
{
public:
...
std::size_t numDisks() const;
...
};
FileSystem& tfs()
{
static FileSystem fs;
return fs;
}
//Directory.h
class Directory
{
public:
Directory(paras);
...
};
Directory::Directory(params)
{
...
std::size_t disks = tfs().numDisks();
...
}