#ifndef Clause2_H
#define Clause2_H
条款2:尽量以const,enum,inline替换#define
//知识点1
//#define APSECT_RATIO 1.653;
//为何不使用宏:因为记号APSECT_RATIO也许从未被编译器看见;也许在编译器开始处理源代码
//之前它就被预处理器移走了。于是记号名称APSECT_RATIO有可能没有进入记号表(symbol table)
//于是当我们运用此常量但获得一个编译错误信息时,可能会带来疑惑,因为这个错误信息会提到1.653而不是APSECT_RATIO。
const double ApsectRatio=1.653;//改为使用const 常量 ApsectRatio肯定会被编译器看见,当然就会进入记号表
//知识点2 class专属常量
//class专属常量,为了将常量的作用域限制于class内,你必须让它成为class的一个成员;而为了确保此常量至多只有一份实体,你必须让它成为一个static成员
//反观#define,我们无法利用#define创建一个class专属常量,因为#define并不重视作用域。一旦宏被定义,它就在其后的编译过程中有效(除非在某处被#undef)。这意味着#define不仅不能够用来定义class专属常量,也不够提供封装性
class GamePlayer
{
private:
static const int NumberTurn=5;
int array[NumberTurn];
};
**//也可以使用 不支持“in-class”定义方式**
class CostEstimate{
private:
static const double FudgeFactor;//位于头文件
};
const double CostEstimate::FudgeFactor=1.35;//实现文件中
//再看下面的代码:
class GamePlayer1
{
private:
enum {NumberTurn=5};//(2)解决方案:使用the enum hack补偿的做法,其理论基础在于:一个属于枚举类型的数值可以权充ints使用
//static const int NumberTurn;(1)
int array[NumberTurn];//(1)处问题出现!当class编译期间需要一个class常量值,就如本例的array的数组声明式
//因为编译器必须在编译的时候知道数组的大小。改用方法(2)
};
//const int GamePlayer1::NumberTurn=5;(1)
//**知识点3 实现宏的时
void f(int a)
{
//…
}
#define CALL_WITH_MAX(a,b) f((a)>(b):(a)?(b))
int a=5,b=0;
//但是如果调用CALL_WITH_MAX(++a,b),就会让a被累加2次,相当于替换成了:f((++a)>b:(++a)?(b))
template<typename T>//解决方案,写成template inline函数
inline void CallWithMax(const T & a,const T & b)
{
f(a>b?a:b);
}
//1.对于单纯常量,最好以const对象或enums替换#define
//2.对于形似函数的宏,最好改用inline函数替换#defines
#endif
本文探讨了在C++编程中,如何避免使用#define宏定义,并提出了const常量、enum枚举和inline函数作为更好的替代方案。文章详细解释了这些方法的优势,包括提高代码的可读性和维护性。

被折叠的 条评论
为什么被折叠?



