尽量使用const替换 #define定义常量的原因: #define 不被视为语言的一部分 宏定义的常量,预处理器只是盲目的将宏名称替换为其的常量值,导致目标码中出现多分对应的常量,而const定义的常量,会进入记号表,使用到该常量的地方使用的同一份,使目标码的量更小点: const可以在类中定义一个class专属常量,其作用域限制于class内.(注:如果一个class专属常量又是static又是整数类型,需要特殊处理.主要不取其地址,则,可以声明并使用但是无须提供定义式.如果,需要取地址,…
其实这个条款分成两部分介绍会比较好,第一部分是用const和enum替换不带参的宏,第二部分是用inline替换带参的宏. 第一部分:用const和enum替换不带参宏 宏定义#define发生在预编译期,而const,enum定义的常量发生在编译期,两者的重要差别在于编译期里的变量是进符号表的,而预编译期的宏是简单的替换,不进符号表.因此,const, enum定义的常量具有以下优势: (1)支持类型检查 (2)支持访问权限 第(1)条优势,其实在Visual Studio编译器也已经对宏也引…
1.首先#define 定义不重视作用域(scope),虽然可以#undef控制,但是不美观,还存在多次替换的问题,以及没有任何封装性. 2.const XXX_XX,保证其常量性以及可控的作用域,如果是指针类型则 const XXXX* const ptr="hello world",也可以完美替换#defin 3.enum hack 替换数组大小问题,和#define 一样不会导致非必要内存(只有在声明enum类型时有内存) 4.宏函数会产生很多问题,没有对参数的各种限制,而inl…
1.#define缺点1 #define NUM 1.2 记号NUM可能没有进入记号表,在调试或者错误信息中,无法知道1.2的含义. 改善:通过const int NUM = 1.2; 2.#deine缺点2 无法利用#define创建一个class专属常量,一旦宏被定义,它就在其后的编译过程中有效(除非遇到#undef). 改善:可以通过const成员变量来满足要求. 3.const成员变量缺点 占用存储空间 改善:通过enum代替 4.对于形似函数的宏,最好改用inline函数替换#defi…
目录 1. 总结 2. 使用const常量或enum替换宏常量 class外部的常量指针 class专属常量 1. 总结 对于单纯常量,最好以const常量或enum替换#define 对于宏代码段,最好改用inline函数替换#define 2. 使用const常量或enum替换宏常量 当我们以const常量替换#define,有两种特殊情况值得说说. class外部的常量指针 第一种是定义class外部的常量指针,这种常量定义式通常放在头文件内以便被不同的源文件使用,因此有必要将指针本身声明…
class GamePlayer{private: static const int NumTurns = 5; int scores[NumTurns]; ...}; 万一你的编译器(错误地)不允许“static整数型class常量“完成”in class初值设定“,可改用所谓的”the enumhack" 补偿做法.其理论基础是:“一个属于枚举类型(enumerated type)的数值可权充ints被使用”,于是GamePlayer可定义如下: class GamePlayer{priva…
原因: 1. 追踪困难,由于在编译期已经替换,在记号表中没有. 2. 由于编译期多处替换,可能导致目标代码体积稍大. 3. define没有作用域,如在类中定义一个常量不行. 做法: 可以用const发挥常量的作用. enum也可:取enum定义的变量地址不合法,取宏也是:而取const变量则合法. 而宏函数的做法,也可以用template加inline替换. ps:但#include和#ifdef等仍然无可替代. 读后感: define的确是奇淫技巧一般的存在: 但在编译期替换会导致运行期难以…
在读<Effective C++>之前,我确实不知道const,enum,inline会和define扯上什么关系,看完感觉收获很大,记录之. define: 宏定义. 在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”.宏定义是由源程序中的宏定义命令完成的.宏代换是由预处理程序自动完成的.由预处理器处理. #define ASPECT_RATIO 1.653 记号名称ASPECT_RATIO也许从未被编译器看见,在编译器处理源代码之前就可能被…
宁可使用编译器而不用预处理器 假设我们使用预处理器: #define ABC 1.56 这标识符ABC也许编译器没看到,也许它在编译器处理源码前就被预处理器移走了,于是“标识符”ABC没有进入标识符列表(symbol table)中.但是当我们编译程序遇到个错误信息时,可能会带来困惑,因为这个错误信息可能会提到1.56而不是ABC,而下面例子在vs2015上编译的时候,错误信息提示ABC未定义的标识符.假如这个ABC不在我们自己定义的头文件中,我们根本无法知道其来源,追踪不到它.解决之道就是使用…
本文的标题也可以改成“用编译器替换预处理器”: const double AspectRatio = 1.653; //最好使用上述代码替换下述代码: #define ASPECT_RATIO 1.653 好处: 记号名称ASPECT_RATIO从未被编译器看见,也许在编译器开始处理源码之前它就被预处理器移走了.于是记号名称ASPECT_RATIO有可能没有进入记号表内. 如果当编译出现错误,这个错误信息有可能会提到1.653,而不是AspecRation,如果宏定义放在不是你写的头文件中,那么…