ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

《Effective C++》rule 02: Prefer consts, enums, and inlines to #defines

2022-04-14 03:31:22  阅读:180  来源: 互联网

标签:02 const 函数 Effective 常量 inlines 定义 替换 define


宏定义的问题

C++ 会在预处理阶段对宏定义进行字符串替换.

因此,如果在一个头文件进行了类似如 #define ASPECT_RATIO 1.653 的宏定义,那么此常量相关的编译错误信息显示的会是 1.653, 而这个宏定义如果不在你写的程序内 (而是它包含的一个头文件内),那么定位问题就会很麻烦.

原因很简单: 宏定义在预处理阶段就被处理,因此使用的名称并没有进入符号表 (symbol table) 中.

如何解决

对于常量,可以使用 const 来代替 #define:

const double AspectRatio = 1.653;

这里,常量 AspectRatio 会进入符号表中,所以会被编译器"看见".

使用常量还有一个好处: 相比 #define 的目标码 (object code) 更小.

因为宏定义是进行字符串替换,在目标码中会进行多次替换;而使用 const 则没有这个问题.

#define 的另一个误用情况

另一个常见的 #define 的误用情况是用它实现 宏 (macros).

宏看起来像函数,但没有函数调用 (function call) 带来的额外开销.

例如:

// 在 a 和 b 的较大值中调用 f
#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) :(b))

由于宏是进行字符串替换,所以写这种宏的时候要记得给所有实参加上小括号,否则可能在调用宏的时候出现错误 (不可预料的行为和类型不安全).

为了使用宏带来的效率同时保证函数的所有可预料行为和类型安全性 (type safety),可以使用 template inline 函数.

例如上面的例子可以改为:

/*
	因为不确定 T 是什么类型,所以这里使用 pass by reference to const 的形式
*/
template<typename T>
inline void callWithMax(const T& a, const T& b) {
	f(a > b ? a : b);
}

可以发现,这里不需要给参数都加上括号.

这里的 callWithMax 是个真正的函数,它有作用域 (scope) 和函数的访问规则,而宏就没有这些东西.

总结

  • 对于单纯的常量,最好用 const 对象或 enum 替换 #define
  • 对于形似函数的宏 (macros),最好用 inline函数替换 #define

标签:02,const,函数,Effective,常量,inlines,定义,替换,define
来源: https://www.cnblogs.com/linrj/p/16142903.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有