条款2:尽量以const、enum、inline替换#define
1> 以const替换#define
• 比如用const double Ratio = 1.653替换#define RATIO 1.653
因为宏定义在预处理阶段就会被替换成其所指代的内容,然后才是对替换后的内容进行编译,因此编译器永远不能发现宏的存在。此时如果宏变量RATIO出现问题,那么编译器只会报出是1.653出现问题,是不是相当莫名其妙?究其原因就是所使用的宏变量压根没进入到符号表中,编译器看不到。
• 如何定义类内常量,就是对该类而言只有一份的那种变量?当然我们会想到static,如果加上const会更好,但此时#define就不行了,如果用#define定义了所谓的私有宏,那么在其定义后都可以访问,因此#define没有scope限制,如下所示:
#include<iostream> class GamePlayer
{
private:
static const int Nums = ; // 常量的声明而非定义
int scores[Nums];
#define NUMS 5 // 定义所谓的私有宏
}; int main()
{
std::cout << NUMS << std::endl; // 可以随时访问,不受类作用域限制
return ;
}
如上,此时的类内常量定义就没有任何意义了。
接着讨论static const定义,定义应该放在哪?
一般而言,我们所定义的类都放在头文件中,那么类内常量的定义当然是放在源文件中了,在源文件中就像下面这样定义即可:
const int GamePlayer::Nums; // 常量在使用前必须定义
当然你也可以在声明时不初始化,等到定义时再赋值也是一样的。
2> 以enum替换#define
我们也可以使用enum来实现类内的常量定义,如下所示:
class GamePlayer
{
private:
enum{ Nums = 5 }; // 以enum定义常量
int scores[Nums];
};
其实enum的行为和#define更像一些,因为我们不能取一个#define的地址,同样也不能取一个enum的地址,但是我们可以取一个const常量的地址。
3> 以inline替换#define
假设我们有如下宏定义:
#define CALL_MAX(a, b) f((a) > (b) ? (a) : (b))
可以替换如下:
template<typename T>
inline void callMax(const T& a, const T& b)
{
f(a > b ? a : b);
}
如上替换之后就不用再担心宏参数的加括号问题,同时也使代码变得简洁明了。再者说,定义类内的private inline函数也毫无问题,而#define绝对不能胜任。
总结:
- 对于单个常量,以const或enum替换#define定义。
- 对于带参数的宏,以inline函数替换#define定义。
条款2:尽量以const、enum、inline替换#define的更多相关文章
- 读书笔记_Effective_C++_条款二:尽量以const, enum, inline替换#define
其实这个条款分成两部分介绍会比较好,第一部分是用const和enum替换不带参的宏,第二部分是用inline替换带参的宏. 第一部分:用const和enum替换不带参宏 宏定义#define发生在预编 ...
- Effective C++阅读笔记_条款2:尽量以const,enum,inline替换#define
1.#define缺点1 #define NUM 1.2 记号NUM可能没有进入记号表,在调试或者错误信息中,无法知道1.2的含义. 改善:通过const int NUM = 1.2; 2.#dein ...
- Effective C++学习笔记 条款02:尽量以const,enum,inline替换 #define
尽量使用const替换 #define定义常量的原因: #define 不被视为语言的一部分 宏定义的常量,预处理器只是盲目的将宏名称替换为其的常量值,导致目标码中出现多分对应的常量,而const定义 ...
- 条款2:尽量以const, enum, inline替换#define
原因: 1. 追踪困难,由于在编译期已经替换,在记号表中没有. 2. 由于编译期多处替换,可能导致目标代码体积稍大. 3. define没有作用域,如在类中定义一个常量不行. 做法: 可以用const ...
- 条款02:尽量以const,enum,inline替换#define
目录 1. 总结 2. 使用const常量或enum替换宏常量 class外部的常量指针 class专属常量 1. 总结 对于单纯常量,最好以const常量或enum替换#define 对于宏代码段, ...
- NO.2: 尽量以const,enum,inline 替换 #define
1.首先#define 定义不重视作用域(scope),虽然可以#undef控制,但是不美观,还存在多次替换的问题,以及没有任何封装性. 2.const XXX_XX,保证其常量性以及可控的作用域,如 ...
- Effective C++ -----条款02:尽量以const, enum, inline替换 #define
class GamePlayer{private: static const int NumTurns = 5; int scores[NumTurns]; ...}; 万一你的编译器(错误地)不允许 ...
- 条款2:尽量使用const ,enum,inline替换define
宁可使用编译器而不用预处理器 假设我们使用预处理器: #define ABC 1.56 这标识符ABC也许编译器没看到,也许它在编译器处理源码前就被预处理器移走了,于是“标识符”ABC没有进入标识符列 ...
- Effective C++之条款2:尽量以const enum inline替换 #define
本文的标题也可以改成“用编译器替换预处理器”: const double AspectRatio = 1.653; //最好使用上述代码替换下述代码: #define ASPECT_RATIO 1.6 ...
- Book. Effective C++ item2-尽量使用const, enum, inline替换#define
##常规变量 c++里面的#define后面的定义部分,是不算代码的一部分的.所以如果你使用#define: #define ASPECT_RATIO 1.653 你希望这个代号ASPECT RATI ...
随机推荐
- mac下的一些常识
1,环境变量 EddydeMacBook-Pro:~ eddy$ vi ~/.bash_profile EddydeMacBook-Pro:~ eddy$ vim /etc/profile Eddyd ...
- python中set和frozenset方法和区别
set(可变集合)与frozenset(不可变集合)的区别:set无序排序且不重复,是可变的,有add(),remove()等方法.既然是可变的,所以它不存在哈希值.基本功能包括关系测试和消除重复元素 ...
- 详解Ossim 4.3控制台
在Ossim 4.2以后的发行版中增加了控制台功能下面加以详细说明,当Ossim 启动之后,在控制台以root身份登录系统后会执行ossim-setup脚本,然后显示如下图1所示,了解这些功能,以及操 ...
- HDOJ1010(BFS)
//为什么bfs不行呢,想不通 #include<cstdio>#include<cstring>#include<queue>using namespace st ...
- flask-admin
初始化 class Admin(app=None, name=None, url=None, subdomain=None, index_view=None, translations_path=No ...
- MyEclipse 中文乱码 史诗级解决方法。也可用于其他编码
最近发现以前写的项目全乱码了.唯独 .java 中的中文全是乱码. 由于,后期的项目把默认编码改成了UTF-8所以就乱了. 每个编码表的编码都不一样.不能直接通过改某个属性来更改达到目的 (除非你是 ...
- 【转载】FPGA功耗的那些事儿
在项目设计初期,基于硬件电源模块的设计考虑,对FPGA设计中的功耗估计是必不可少的. 笔者经历过一个项目,整个系统的功耗达到了100w,而单片FPGA的功耗估计得到为20w左右, 有点过高了,功耗过高 ...
- poj1035 Spell checker
这题目比较简单,把思路搞清楚就可以啦. #include <stdio.h> #include <string.h> +][]; int init(){ ; while(~sc ...
- oracle查询使用频率和磁盘消耗需要缓存大小
SELECT * FROM (SELECT Sql_Text, Sql_Id, Cpu_Time FROM V$sql ORDER BY Cpu_Time DESC) ORDER BY Rownum ...
- mq队列管理器命令
dspmq: 队列管理器显示 QMCIPSA-------队列管理器 runmqsc QMSAA 运行查找Q队列名 运行MQ命令 runmqsc QmgrName 如果是默认队列管理器,可以不带其名 ...