前言

在面向过程语言,如 C 语言中,#define 非常常见,也确实好用,值得提倡。但在如今面向对象的语言,如 C++ 语言中,#define 就要尽量少用了。

为何在 C++ 中就要少用了呢?

这是因为 #define 机制只是简单的字符替换,这样一方面你无法对 #define 定义的东西加入一些C++语法元素,因此限制了面向对象编程语言的威力;

另一方面编译器不能获取到你所定义的变量类型/函数类型,因此无法提供全面的检测机制,导致隐藏 bug 增多。

所以要想出对 #define 机制进行替代的思路。

思路一:使用类变量代替宏全局变量

步骤:

1. 在类定义式内声明 static 成员

2. 在类的实现文件内初始化该成员

3. 由该类派生出的任何对象都可以访问这个成员。

示例代码:

 #include <iostream>

 using namespace std;

 class CA
{
public:
static const float a;
}; const float CA::a = 5.0; int main ()
{
cout << CA::a << endl; cin.get(); return ;
}

思路二:类定义中就要用到的全局常量使用 enum 实现

在思路一中,如果类 CA 要使用到 a,比如类中要声明一个数组,则下面语句是非法的:int arrayA[a];。为啥?因为在类定义的头文件中,编译器还获取不到 a 的具体值。因此,可以采用所谓的 the enum hack 做法来解决这个问题。

 enum { ArrayNum= };
int array[ArrayNum];

思路三:采用 template inline 函数代替宏函数

预处理器的一个很重要的功能是实现宏函数,如下面这个宏函数能够返回 a 和 b 之间较大的值而不论a 和 b的具体类型:

 #define CALL_WITH_MAX(a, b) f((a)>(b)?(a):(b))

但这样的实现有好几个漏洞,读者不放试着自己找出来。

而采用 template inline 函数不单没有这些漏洞,还可以给它添加各种语法机制,比如将它定义为某个类的成员函数。下面的代码演示了 template inline 函数实现改功能的具体做法:

 template <typename T>
inline void callWithMax (const T &a, const T &b)
{
f(a>b?a:b);
}

小结

这三个思路在很多时候都可以替换掉 #define。

然而,#define 并没有彻底退出舞台,它提供的条件编译功能目前也是非常实用的。

第一篇:尽量多的以 const/enum/inline 替代 #define的更多相关文章

  1. 尽量多的以 const/enum/inline 替代 #define

    前言 在面向过程语言,如 C 语言中,#define 非常常见,也确实好用,值得提倡.但在如今面向对象的语言,如 C++ 语言中,#define 就要尽量少用了. 为何在 C++ 中就要少用了呢? 这 ...

  2. Book. Effective C++ item2-尽量使用const, enum, inline替换#define

    ##常规变量 c++里面的#define后面的定义部分,是不算代码的一部分的.所以如果你使用#define: #define ASPECT_RATIO 1.653 你希望这个代号ASPECT RATI ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Druid对比Impala/Shark

    Druid 和 Impala Shark 的对比取决于产品要求, 取决于系统是设计成做什么的 Druid 被设计成 一直在线, 高可用性    实时插入数据    分片分块形式的任意查询据我所知 Im ...

  2. mvn test 中文乱码

    有两种解决办法: 1.设置encoding:<argLine>-Dfile.encoding=UTF-8</argLine>,解决读取文件中的中文乱码问题 2.升级maven- ...

  3. android: android中dip、dp、px、sp和屏幕密度

    android中dip.dp.px.sp和屏幕密度 转自:http://www.cnblogs.com/fbsk/archive/2011/10/17/2215539.html 1. dip: dev ...

  4. ZT:有些人,活了一辈子,其实不过是认真过了一天,其余时间都在重复这一天而已

    出处:http://news.163.com/17/1011/19/D0G7UEDS0001982T.html 有些人,活了一辈子,其实不过是认真过了一天,其余时间都在重复这一天而已,也有人每天不重样 ...

  5. Appium Python 一:环境搭建

    安装Android SDK以及模拟器 由于Appium依赖于Android SDK,所以需要先安装SDK. 这里由于需要在Android模拟器上跑测试用例,所以同时需要安装Android 模拟器. 1 ...

  6. JUC同步器框架

    The java.util.concurrent Synchronizer Framework 前提 AQS(java.util.concurrent.locks.AbstractQueuedSync ...

  7. 2014秋C++第5周项目1參考-见识刚開始学习的人常见错误

    课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703,实践要求见http://blog.csdn.net/sxhelijian/a ...

  8. 【SSH网上商城项目实战30】项目总结(附源码下载地址)

    项目基本完成了,加上这个总结,与这个项目相关的博客也写了30篇了,积少成多,写博客的过程是固化思路的一个过程,对自己很有用,同时也能帮助别人.顺便说个题外话,在学习的过程中肯定会遇到很多异常出现,我们 ...

  9. C# 播放H264裸码流

    要播放H264裸码流,可以分拆为以下三个工作: 1.解码H264裸码流获取YUV数据 2.将YUV数据转换为RGB数据填充图片 3.将获取的图片进行显示 要完成工作1,我们可以直接使用海思的解码库,由 ...

  10. spring boot和thrift、zookeeper建立微服务

    原文地址:http://www.cnblogs.com/skyblog/p/5535418.html Spring cloud适应于云端服务,也适用于企业信息化SOA建设.spring boot也是r ...