【Effective C++ 条款02 笔记】尽量以const,enum,inline替换#define

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

部分来源:https://blog.csdn.net/weixin_37992828/article/details/81117036

关于const

在使用宏定义的时候,比如

#define pi 3.14159

宏pi根本没有进入记号表,当使用这个宏但是编译错误时,只会提示是3.14159出现了错误。如果这一行宏定义出现在不是程序员自己写的头文件时,也就查不到这个3.14159到底是出现在哪里了。因此,提倡使用常量来替换宏定义

const double pi = 3.14159;

关于enum hack

从一个例子开始吧

class Game {
    
    
private:
    static const int GameTurn = 10;
    int scores[GameTurn];
};

对于支持类内初始化的C++编译器,这段代码可以编译通过。

但是较老的C++编译器,可能不支持类内初始化,这样我们的静态常量,必须要在类外初始化。如下:

class Game {
    
    
private:
    static const int GameTurn;
    int scores[GameTurn];
};
const int Game::GameTurn = 10;

如果没有int scores[GameTurn];,这段代码就可以用不支持类内初始化的编译器通过了。

但因为 int scores[GameTurn]; 用到了GameTurn,而GameTurn的值不能确定。所以会报如下错误。

enum_hack.cpp:5: error: array bound is not an integer constant

这种情况下,如果我们仍然不想用硬编码的数字指定数组的大小,就可以考虑这篇文章的主角: enum hack 了。

使用enum hack的技巧,其思想就是把GameTurn定义为一个枚举常量。上面的代码可以写为:

class Game {
    
    
private:
    // static const int GameTurn;
    enum {
    
    GameTurn = 10};
    int scores[GameTurn];
};
// const int Game::GameTurn = 10;

这样代码就可以编译通过了。

《Effective C++》中这样描述enum hack的好处:

  1. enum hack的行为更像#define而不是const,如果你不希望别人得到你的常量成员的指针或引用,你可以用enum hack替代之。(为什么不直接用#define呢?首先,因为#define是字符串替换,所以不利于程序调试。其次,#define的可视范围难以控制,比如你怎么让#define定义的常量只在一个类内可见呢?除非你用丑陋的#undef
  2. 使用enum hack不会导致 “不必要的内存分配”。
  3. enum hack是模板元编程的一项基本技术,大量的代码在使用它。当你看到它时,你要认识它。

关于inline

使用#difine宏定义的另一个作用是宏函数,但是宏函数只是长得像函数,实际并不是函数,只是单纯的文本替换

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

上面的宏定义根据a,b的值调用函数f,函数f是一个真正的函数

那么根据传入++a>b和++a<b这两种情况,a的递增次数是不一样的

这种情况就是使用宏函数降低函数调用开销的弊端,那么为了解决这个问题,还同时要降低函数调用的弊端,可以使用inline函数

inline void compareAB(int& a, int&b) {
    
    
	f(a>b?a:b);
}

此时的compareAB是一个真正的函数,还不用为每一个实参都加括号

总结:

1、对于纯变量,最好用const和enums替换#define

2、对于宏函数,最好用inline函数替换

猜你喜欢

转载自blog.csdn.net/weixin_44484715/article/details/121215395