01 视C+为一个语言联邦
02 尽量以const,enum,inline替换#define
#deinfe 预处理器的字符串替换,其本身不被视为语言的一部分。
尽量以编译器替代预处理器。
1对与int常量 最好用enum或const替代#define
2对于其他类型的变量,尽量使用const 常量替代
3对于形似函数的宏 尽可能用inline替代#define
意义:
使用const或者 enum而非#define定义变量,变量本身一定能进入符号表,产生编译错误的时候,也能知道容易找到错误原因所在
使用#define定义的形似函数的宏 ,会招致许多不必要的麻烦,首先需要宏中实参添加括号 ,其次形如下列宏定义的函数!带来的麻烦可想而知了
#define MAX(a,b) a>b?a:b
MAX(i++,j)
使用inline的产生便是 兼顾了#define宏定义函数为效率所带来的提升,并且消除了因为字符替换而造成的语义麻烦。inline依然会在所被调用的地方展开,函数帧栈所需要的开销,不会产生形如#define的麻烦。
03尽可能使用const
注意consst char*const p类型
const本身有助于侦测语法错误,const可被施加于函数本体,对象,参数,返回类型
04确定对象被使用前初始化
05了解C++默默调用并使用了哪些函数
06 若不想使用编译器自动生成的函数,就应该明确拒绝
class Uncopyable {
protected: // allow construction
Uncopyable() {} // and destruction of
~Uncopyable() {} // derived objects...
private:
Uncopyable(const Uncopyable&); // ...but prevent copying
Uncopyable& operator=(const Uncopyable&);
};
并使用当前类继承之。
class HomeForSale: private Uncopyable { // class no longer
... // declares copy ctor or
}; // copy assign. operator
当尝试使用member或者friend函数 调用HomeForSale类的copy构造或者copy assingment操作符,这些函数编译器生成板会尝试调用base class的相应函数,显然会被编译器拒绝的,这样就完全拒绝了编译器自动生成该类函数,防止非期望调用而自动生成。
07 为多态基类声明virtual析构函数
virtual 函数产生的虚函数表会增加类内存大小,因此除非是多态性质的base class ,否则不应该随意声明
通常判断一个base class是否带有多态性质,也就是看是否有定义virtual函数如果是,那么为其声明虚析构函数。如果不这样做,基类指针实现多态 析构函数调用的只能是基类定义的析构函数。
08别让异常逃离析构函数
析构函数绝对不要吐出异常,如果一个被析构的函数调用的函数可能抛出异常,析构函数应该捕捉任何一长,然后吞下他们(不传播)或结束程序。
如果客户需要对某个操作函数运行期间抛出的异常作出反映,那么class应该提供一个普通函数(而非析构函数中)执行该操作
09绝不在构造和析构过程中调用virtual函数
在base class构造和析构期间不要调用virtual函数,因为这类函数从不下降至derived class
这样做的一个理由是,virtual 函数调用期间,即基类构造期间,子类的成员尚未初始化,如果这时候virtual下降到子类 ,那么使用为初始化的成员变量是十分危险
10令operator=返回一个reference to *this
约定俗成,规范常识
11在operator=中处理自我赋值
for security
12复制对象时勿忘其每一个成分
copy函数因该确保复制“对象内所有成员变量”及“所有base class”部分
不要尝试某个copying函数实现另一个copying,应该将共同技能放进第三个函数中,并由两个coping函数共同调用
13以对象管理资源
14在资源管理中心小心copying的行为