视c++为一个语言联邦
尽量以const,enum,inline替换#define
尽可能使用const
确定对象被使用前已先被初始化
视C++为一个语言联邦
C++: C with Classes
。c++可以看成是C语言与OOP的结合体,并引入STL新特性:
- C: C语言部分;
- Object-Oriented C++: C++中OOP部分;
- Template C++: C++中模板部分(泛型);
- STL: C++标准库(泛型)。
尽量以const,enum,inline替换#define
以编译器替换预处理器
。#define缺点:
- 预处理阶段处理,错误提示不明确;
- 盲目替换,导致存在多份;
- 替换时展开导致语义错误
使用const,enum和inline替换的优点:
- 编译阶段处理,明确的错误提示;
- 单份代码。
///
// 预处理器处理
// 预处理阶段 --> 盲目替换 --> 编译器
// - 预处理阶段处理,错误提示不明确
// - 盲目替换,导致存在多份
// - 替换时展开导致语义错误
#define ASPECT_RATIO 1.653
///
// 编译器处理
// 编译器
// - 编译阶段处理,明确的错误提示
// - 单份代码
const double AspectRatio = 1.653;
class GamePlayer
{
private:
enum { NumTurns = 5 }; // 类专属常量enum定义
private:
static const int NumTurns; // 类专属常量const定义
};
const int GamePlayer::NumTurns = 5;
// inline模板定义
template<typename T>
inline T callWithMax(const T &a, const T &b)
{
return (a > b ? a : b);
}
方法:
- 对于单纯常量,最好以const或者enum替换#define;
- 对于形似函数的宏,最好改用inline函数替换#define。
尽可能使用const
const定义不被改动的语义约束
。特点:
- const出现在
*
号左边,表示被指物是常量;const出现在*
号右边,表示指针自身是常量;如果出现在*
号两边,表示被指物和指针都是常量;
char a = "Hello World!";
const char *p = a; // a不可变
char* const p = a; // p不可变
const char* const p = a; // p和a都不可变
- 如果被指物不可变,const写在类型前和写在类型后意义相同:
void f1(const Widget *pw);
void f2(Widget const *pw); // 意义相同
- const成员函数:bitwise constness和“概念上的常量性”。
确定对象被使用前已先被初始化
解决使用与初始化的顺序问题:永远在使用对象之前将它初始化
。
区别 初始化 和 赋值 :
ABEntry::ABEntry(const std::string &name, const std::string &address,
const std::list<PhoneNumber> &phones)
{
// 此处为赋值,并非初始化
theName = name;
theAddress = address;
thePhones = phones;
numTimesConsulted = 0;
}
ABEntry::ABEntry(const std::string &name, const std::string &address,
const std::list<PhoneNumber> &phones)
:theName(name),
theAddress(address),
thePhones(phones),
numTimesConsulted(0) // 此处为值列初始化
{
}
解决使用和初始化的先后问题:
// 将每个non-local static对象搬到自己的专属函数内。
// 单例模式常见手法
class FileSystem {...};
FileSystem& tfs()
{
static FileSystem fs;
return fs;
}
class Directory {...};
Directory::Directory(params)
{
...
std::size_t disks = tds().numDisks();
...
}
方法:
- 内置对象进行手工初始化,因为C++不保证初始化它们;
- 构造函数使用初值列初始化;初值列成员变量的排列次序应该与tam在class中声明次序相同;
- 以local static对象替换non-local static对象解决“跨单元的初始化次序”问题。