宁可以编译器替换预处理器。
宏的缺点:
由于#define宏定义由预处理器管理,通常可以理解为宏即为替换,例:
#define LENSIZE 20在预处理时,编译器会将代码中的所有LENSIZE简单的替换为20,因此宏常会出现一些难以预料的问题。按书中所述:LENSIZE也许从未被编译器看见,记号名称LENSIZE有可能未进入符号表(symbol table)内。当出现异常报错时,错误信息可能是20而非LENSIZE,如果LENSIZE定义在某个头文件中,这样对于错误的追踪便会相对麻烦。并且宏不重视作用域,不能提供任何封装性。
在使用宏时,更容易发生的另一个问题是,例:
#define MAX(a,b) a > b ? a : b int main() { int a = 8; int b = 6; MAX(a,b); return 0 }这是基础的宏函数应用,由于宏带有一定的泛型意味,导致这样看似使用起来更方便,但由于宏只是简单的替换,便会导致问题
}int main { MAX(++a,b); //将宏替换过来便能发现问题 //++a > b ? ++a : b //显然变量++a操作进行了两次 return 0;我们知道在使用宏时,通常要加上括号以保证替换后优先级的问题,可是上面这个问题却仍然解决不了,可能在实际应用中不会出现这样的情况,或者会加上相应的参数检验及异常处理,但是为了用一个宏函数而花大量功夫去维护不是本末倒置么。
鉴于宏在使用中有着种种不便的地方(当然好处也有很多,只是针对此处环境我们对好处不作分析),书中建议以const,enum及inline代替宏的功能。
int const Arr_size = 20; //#define ARR_SIZE 20 template<class Type> inline Type Max(Type a,Type b) { return a >b? a : b; } //#define MAX ....
至于enum hack,由于const是可以取地址的,而宏无法被取地址,这一点enum更像宏一点,因此当出现某种情况你不想让别人获得你整数常量的pointer 或 reference时,使用enum声明整数常量便可以达到要求。
《Effctive C++》读书笔记--(02)Prefer consts,enums,and inlines to #defines
最新推荐文章于 2023-02-14 13:47:44 发布
本文深入探讨了宏定义在编程中的局限性,包括符号表管理问题、作用域限制以及封装性不足等,并提出使用const、enum、inline等替代方法来改进编程实践。
386

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



