前言

  在面向过程语言,如 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. 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. 使用System.Timers.Timer类实现程序定时执行

    使用System.Timers.Timer类实现程序定时执行 在C#里关于定时器类有3个:System.Windows.Forms.Timer类.System.Threading.Timer类和Sys ...

  2. 分析与提取QQ木马盗号技术

    程序大致的流程如下图: 因为是用画图工具画的,所以大家就将就看下把,有什么不对的地方请多多指教: 程序是用Delphi写的,只有加载器加了个upx壳,其他的都没有加壳:所以分析起来就比较简单了: 这个 ...

  3. POJ 3094 Quicksum 难度:0

    http://poj.org/problem?id=3094 #include<iostream> #include <string> using namespace std; ...

  4. 从报错“无效操作,连接被关闭”探究Transaction的Timeout超时机制

    1.报错如下:Invalid Operation the connection is closed,无效操作,连接被关闭.这个错误是并不是每次都报,只有在复杂操作.大事务的情况下才偶然报出来. sta ...

  5. Program L 暴力求解

    Description The GeoSurvComp geologic survey company is responsible for detecting underground oil dep ...

  6. java接收键盘输入

    System.out.print("Please input String to check:");//提示输入 Scanner sc=new Scanner(System.in) ...

  7. Enumeration 接口

    Enumeration是遍历集合元素的一种方法. Enumeration中只有两个方法: 1.hasMoreElements()  测试此枚举是否包含更多的元素. 2.nextElement()  如 ...

  8. [转]source inslght使用指导

    作为一个开放源代码的操作系统,Linux附带的源代码库使得广大爱好者有了一个广泛学习.深入钻研的机会,特别是Linux内核的组织极为复杂,同时,又不能像windows平台的程序一样,可以使用集成开发环 ...

  9. SharePoint 2013 开发——工作流架构

    博客地址:http://blog.csdn.net/FoxDave SharePoint 2013的工作流较之前有了不同,第一次真正地作为独立的服务的概念推出了.这意味着SharePoint工作流不再 ...

  10. 分享Windows Server 2012 R2的获取正版密钥方法

    然后使用“我有ISIC卡”验证,目前可用号码:S420546009858. 分享Windows Server 2012 R2的获取正版密钥方法. 首先登陆dreamspark注册一个账号https:/ ...