前言

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

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

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

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

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

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

  步骤:

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

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

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

  示例代码:

  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. class CA
  6. {
  7. public:
  8. static const float a;
  9. };
  10.  
  11. const float CA::a = 5.0;
  12.  
  13. int main ()
  14. {
  15. cout << CA::a << endl;
  16.  
  17. cin.get();
  18.  
  19. return ;
  20. }

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

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

  1. enum { ArrayNum= };
  2. int array[ArrayNum];

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

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

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

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

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

  1. template <typename T>
  2. inline void callWithMax (const T &a, const T &b)
  3. {
  4. f(a>b?a:b);
  5. }

小结

  这三个思路在很多时候都可以替换掉 #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. Effective C++阅读笔记_条款2:尽量以const,enum,inline替换#define

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

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

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

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

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

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

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

  9. 尽量用const,enum,inline代替define

    在读<Effective C++>之前,我确实不知道const,enum,inline会和define扯上什么关系,看完感觉收获很大,记录之. define: 宏定义. 在编译预处理时,对 ...

随机推荐

  1. JBOSS常用端口说明

    1.jboss 的端口修改位置总结 Jboss通常占用的端口是1098,1099,4444,4445,8080,8009,8083,8093这几个, 默认端口是8080 在windows系统中: 10 ...

  2. LA 5059 - Playing With Stones

    博弈 SG  由于每个a太大,没有办法递推,但是可以找规律 a为偶数  SG(a)=a/2 a为奇数  SG(a)=SG(a/2) 代码: #include <iostream> #inc ...

  3. MSP430x1_4_6x之问题总结

    01:MSP430端口上电复位的初始值是不确定的:所以使用是都要初始化:比如加下面的语句或者加你使用的端口就行了:  /*下面六行程序关闭所有的IO口*/    P1DIR = 0XFF;P1OUT ...

  4. [C/C++]C/C++相关网站

    1.http://en.cppreference.com What is the purpose of this site? Our goal is to provide programmers wi ...

  5. 程序中double类型的数输出为什么要用lf

    在c89和c++中double的输入和输入输出都用%lf 在c99中,double的输出必须用%f,而输入要用%lf oIER一般使用c++,所以输出直接%lf即可.

  6. iOS中nil、Nil、NULL、NSNull详解(转)

    ObjC 里面的几个空值符号经常会差点把我搞死,这些基础的东西一点要弄清楚才行,以提高码农的基本素质. nil nil 是 ObjC 对象的字面空值,对应 id 类型的对象,或者使用 @interfa ...

  7. python黑帽子源码

    https://www.nostarch.com/download/BHP-Code.zip https://yunpan.cn/cPvLPWMTdWJRu  访问密码 4243

  8. SVG 2D入门7 - 重用与引用

    前面介绍了很多的图形元素,如果很多图形本身是一样的,需要每次都去定义一个新的么?我们能否共用一些图形呢?这是这节的重点 - SVG元素的重用. 组合 - g元素      g元素是一种容器,它组合一组 ...

  9. 二、XML约束

    XML约束有dtd约束和Schema约束两种 dtd约束:可以在xml内部写dtd约束也可以在xml中引用外部dtd文件 book.dtd<!ELEMENT 书架 (书+)>    < ...

  10. 如何通过 GT 快速开始性能测试?

    http://gt.tencent.com/docs/a/2.1/GTAndroidQuickStart.pdf Summary 安装 GT(GT.apk)后,不需要连接 PC 和在被测应用中插入代码 ...