Item 2:避免使用define Effective C++笔记
来源:互联网 发布:飞狐淘宝客cms 编辑:程序博客网 时间:2024/04/29 14:41
Item 2: Prefer consts, enums, and inlines to #defines
尽量使用常量、枚举和内联函数,代替#define
。我们知道#define
定义的宏会在编译时进行替换,属于模块化程序设计的概念。 宏是全局的,面向对象程序设计中破坏了封装。因此在C++中尽量避免它!
接着我们具体来看#define
造成的问题。
不易理解
众所周知,由于预处理器会直接替换的原因,宏定义最好用括号括起来。#define
函数将会产生出乎意料的结果:
#define MAX(a,b) a>b?a:bMAX(i++,j)
i
自加次数将取决于j
的大小,然而调用者并不知情。宏的行为不易理解,本质上是因为宏并非C++语言的一部分,它只是源代码的预处理手段。
不利于调试
宏替换发生在编译时,语法检查之前。因此相关的编译错误中不会出现宏名称,我们不知道是哪个宏出了问题。例如:
#define PERSON alicePERSON = bob;
如果alice
未定义,PERSON=bob;
便会出错:use of undeclared identifier 'alice'
。 然而我们可能不知道alice
是什么东西,PERSON
才是我们定义的“变量”。
宏替换是在预处理过程中进行的,原则上讲编译器不知道宏的概念。然而,在现代的编译器中(例如Apple LLVM version 6.0
), 编译器会记录宏替换信息,在编译错误中给出宏的名称:
test.cpp:8:5: error: use of undeclared identifier 'alice' PERSON = bob; ^test.cpp:4:16: note: expanded from macro 'PERSON'#define PERSON alice; ^
于是,Meyers提到的这个问题已经不存在了。然而作者的本意在于:尽量使用编译器,而不是预处理器。 因为#define
并不是C++语言的一部分。
enum 比 const 更好用
既然#define
不能封装在一个类中,我们可以用static const
来定义一个常量,并把它的作用于局限在当前类:
class C{ static const int NUM = 3; int a[NUM];};
通常C++要求所有的声明都给出定义,然而数值类型(char
, int
, long
)的静态常量可以只给声明。这里的NUM
就是一个例子。 然而,如果你想取NUM
的地址,则会得到编译错误:undefined symbol NUM
。为此,通常你需要同时给出定义:
class C{ static const int NUM = 3; int a[NUM];};const int C::NUM;
因为声明
NUM
时已经给定了初始值,定义时不允许再次给初始值。
如果使用enum
,事情会简单很多:
class C{ enum { NUM = 3 }; int a[NUM];};
除非注明,本博客文章均为原创,转载请以链接形式标明本文地址: http://harttle.com/2015/07/20/effective-cpp-2.html
- Item 2:避免使用define Effective C++笔记
- 《Effective C#》 Item 27:避免使用 ICloneable接口
- 《Effective C#》 Item 28: 避免使用类型转换操作符
- Effective JavaScript Item 10 避免使用with
- Effective C++----3rd Edition, Item 2:用consts,enums和inlines取代#define
- <Effective Mordern C++>笔记:Item 2:Understand auto type deduction.
- Effective Java(2nd Edition) Item 59 避免使用不必要的受检查异常(译文)
- Effective Java(2nd Edition) Item 48 如果需要精确结果,请避免使用float与double(译文)
- 《Effective Modern C++》Item 2总结
- Effective-Objective-C-读书笔记-Item-2
- Effective Objective-C 2.0: Item 4: Prefer Typed Constants to Preprocessor #define
- <Effective Mordern C++>笔记:Item 3:Understand decltype .
- 《Effective C#》Item 22:避免返回类内部成员的引用
- Effective JavaScript Item 29 避免使用非规范的Stack Inspection属性
- 《Effective C#》Item 12:推荐使用成员初始化语句
- 《Effective C#》Item 14:使用构造函数初始化语句
- 《Effective C#》Item 19:推荐在继承中使用接口
- 《Effective C#》Item 12:推荐使用成员初始化语句
- 在VIM下写C++能有多爽?
- Item 1:将C++视作一系列的语言 Effective C++笔记
- poj 1236 Network of Schools(强连通分量)
- Marvell发布4核A53芯片 基带支持Cat.7 LTE---ESM
- RGB、YUV和YCbCr
- Item 2:避免使用define Effective C++笔记
- Android实现浮层的上下滑动(支持内部添加View)
- UI架构设计的演化
- Item 3:尽量使用常量 Effective C++笔记
- ural 1136. Parliament 中后序建树
- 数据结构学习——Huffman树及其应用
- 资源网站
- linux chmod命令
- 完美解决程序启动,Activity之间切换,黑屏问题