zoukankan      html  css  js  c++  java
  • 第一篇:尽量多的以 const/enum/inline 替代 #define

    前言

           在面向过程语言,如 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 0;
    20 }

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

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

    1 enum { ArrayNum=5 };
    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 并没有彻底退出舞台,它提供的条件编译功能目前也是非常实用的。

  • 相关阅读:
    freopen stdout 真的更快?
    【评分】第二次作业——个人项目实战
    【评分】第二次作业-数独-第一次测试成绩
    姑娘你大胆地往前走——答大二学生XCL之八问
    第二次作业-数独-初步测试日志
    第二次作业——个人项目实战
    关于C#的随机数
    必须展示窗口才能截图怎么办,伪后台截图思路
    Winform 奇怪的 英文字体错乱显示问题
    wpf 解决 WPF SelectionChanged事件向上传递造成重复执行不想执行的函数的问题
  • 原文地址:https://www.cnblogs.com/muchen/p/6353725.html
Copyright © 2011-2022 走看看