在读《Effective C++》之前,我确实不知道const,enum,inline会和define扯上什么关系,看完感觉收获很大,记录之。

define: 宏定义。 在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。由预处理器处理

#define ASPECT_RATIO  1.653

记号名称ASPECT_RATIO也许从未被编译器看见,在编译器处理源代码之前就可能被预处理器移走了。于是记号就有可能没有进入到符号表中。(在符号表中,程序源代码中的每个标识符都和它的声明或使用信息绑定在一起,比如其数据类型、作用域以及内存地址)这样当使用该常量但获得编译错误信息时,错误信息可能只有1.653,而不会提到ASPCT_RATIO,而这个宏定义可能位于别人写的一个头文件中,这样你就无从查起,这个1.653是啥呢?Only God knows。 因为它可能没被记录到符号表中。

解决办法就是用一个常量替换上面的宏(#define)。

const double ASPECT_RATIO = 1.653

作为一个语言常量,肯定会被编译器看到,并被记录到符号表中。而且对于float型常量来说,使用常量会比使用宏定义需要更少的码,因为预处理器“盲目地将宏名称ASPECT_RATIO替换为 1.653可能会导致目标码(object code)中出现多份1.653”。若改用常量就不会出现这种情况。

用常量替换define需要注意的情况:

1. 定义常量指针

由于常量定义式通常位于头文件内(以便被不同的源码含入),因此有必要将指针声明为const。例如要在头文件内定义一个常量的char*字符串,需要写两个const。

const char* const authorName = "Scot Meryers"

第一个const表示指针指向的是一个常量字符串,不可以修改,第二个const表示该指针 authorName是一个const类型的指针,即指针也不能修改,不能让该指针指向其他字符串。

2. class专属常量

为了将常量的作用于限制于class内,必须让它成为class的一个成员;而为确保此常量只有一份实体,必须让它成为一个static成员。

class Gameplayer
{
private:
static const int NumTurns = ;
int scores[NumTurns];
//...
}

但VC编译器不支持这种行为:不允许static成员在声明式中获取初值(而gcc 4.6.3可以)。而数组在编译的时候必须指定大小,这个时候怎么办呢?可以用“enum hack”来补偿这一不足。 enum hack指的是不带实例的无标记的enum。 可以将 static const int NumTurns =5 替换为 enum {NumTurns=5};“enum hack”是模板元编程(template metaprogramming)的基础技术。

忠告:

1. 对于单纯常量,最好以const或者enum代替#define

2. 对于形似函数的宏,最好改用inline函数代替#define

尽量用const,enum,inline代替define的更多相关文章

  1. NO.2: 尽量以const,enum,inline 替换 #define

    1.首先#define 定义不重视作用域(scope),虽然可以#undef控制,但是不美观,还存在多次替换的问题,以及没有任何封装性. 2.const XXX_XX,保证其常量性以及可控的作用域,如 ...

  2. Effective C++学习笔记 条款02:尽量以const,enum,inline替换 #define

    尽量使用const替换 #define定义常量的原因: #define 不被视为语言的一部分 宏定义的常量,预处理器只是盲目的将宏名称替换为其的常量值,导致目标码中出现多分对应的常量,而const定义 ...

  3. 读书笔记_Effective_C++_条款二:尽量以const, enum, inline替换#define

    其实这个条款分成两部分介绍会比较好,第一部分是用const和enum替换不带参的宏,第二部分是用inline替换带参的宏. 第一部分:用const和enum替换不带参宏 宏定义#define发生在预编 ...

  4. Effective C++阅读笔记_条款2:尽量以const,enum,inline替换#define

    1.#define缺点1 #define NUM 1.2 记号NUM可能没有进入记号表,在调试或者错误信息中,无法知道1.2的含义. 改善:通过const int NUM = 1.2; 2.#dein ...

  5. 条款2:尽量以const, enum, inline替换#define

    原因: 1. 追踪困难,由于在编译期已经替换,在记号表中没有. 2. 由于编译期多处替换,可能导致目标代码体积稍大. 3. define没有作用域,如在类中定义一个常量不行. 做法: 可以用const ...

  6. 条款2:尽量使用const ,enum,inline替换define

    宁可使用编译器而不用预处理器 假设我们使用预处理器: #define ABC 1.56 这标识符ABC也许编译器没看到,也许它在编译器处理源码前就被预处理器移走了,于是“标识符”ABC没有进入标识符列 ...

  7. 条款02:尽量以const,enum,inline替换#define

    目录 1. 总结 2. 使用const常量或enum替换宏常量 class外部的常量指针 class专属常量 1. 总结 对于单纯常量,最好以const常量或enum替换#define 对于宏代码段, ...

  8. Effective C++ -----条款02:尽量以const, enum, inline替换 #define

    class GamePlayer{private: static const int NumTurns = 5; int scores[NumTurns]; ...}; 万一你的编译器(错误地)不允许 ...

  9. Effective C++之条款2:尽量以const enum inline替换 #define

    本文的标题也可以改成“用编译器替换预处理器”: const double AspectRatio = 1.653; //最好使用上述代码替换下述代码: #define ASPECT_RATIO 1.6 ...

随机推荐

  1. [CF1060F]Shrinking Tree

    description codeforces 给一棵\(n\)个节点的树,每次等概率选择树中剩下边的一条进行缩边,这条边的两个端点有相同的概率被保留,求最后每个点被留下的概率. data range ...

  2. [洛谷P3931]SAC E#1 - 一道难题 Tree

    题目大意:给你一棵带权有根树,可以切断一些边,问使得根和叶子节点不连通的最小代价. 题解:做了一天的网络流,这道题显然可以用最小割来做,但是也可以用树形$DP$,基本同[SDOI2011]消耗战,这道 ...

  3. 2018牛客多校第五场 E.room

    题意: 一共有n个宿舍,每个宿舍有4个人.给出第一年的人员分布和第二年的人员分布,问至少有多少人需要移动. 题解: 对于第一年的每个宿舍,向今年的每种组合连边.流量为1,费用为(4 - 组合中已在该宿 ...

  4. BZOJ3992:[SDOI2015]序列统计——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3992 https://www.luogu.org/problemnew/show/P3321 小C ...

  5. PLAN OF HEOI(unfinished)

    Au:整体二分/计算几何/多项式/fwtAg:可持久化重量平衡树/线段树分治/线段树合并/最短路树/最短路DAGCu:三分Up:博弈论/置换群/杜教筛/矩阵树定理/BSGS/动态树分治/网络流(线性规 ...

  6. ADS 安装失败后在此安装在Modify Repair Remove界面循环问题解决

    估计是因为Win7和ADS不兼容的原因,第一次安装ADS后一直停在100%的位置,等了好久也没有反应.于是我点了Cancel.准备从新安装,于是就发生了下面的问题:一直在Modify Repair R ...

  7. C#学习之自定义数组及其排序

    在C#中对数组的定义比较灵活.这里着重说一下自定义数组和Array类的排序. 在Array类中通过属性Length就可以获取整个数组中数据的数量,可以通过foreach迭代数组. 使用Rank属性可以 ...

  8. POJ 2976 二分

    Dropping tests Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12515   Accepted: 4387 D ...

  9. 有向图的强联通分量 Tarjan算法模板

    //白书 321页 #include<iostream> #include<cstdio> #include<cstring> #include<vector ...

  10. 可能是国内最火的开源项目 —— C/C++ 篇

    程序员们,在北上广你还能买房吗? >>>   推荐阅读: 可能是最火的开源项目 -- Java 篇 可能是国内最火的开源项目 -- PHP 篇 可能是国内最火的开源项目 -- Pyt ...