从一个例子开始吧

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是模板元编程的一项基本技术,大量的代码在使用它。当你看到它时,你要认识它。

不知道我的理解是否有误,欢迎讨论。

C++的Enum hack的更多相关文章

  1. enum hack

    关于占用内存的大小,enum类型本身是不占内存的,编译器直接替换.但是enum类型的变量肯定是占内存的. class A{ public: //enum类型本身不占内存 enumEnumTest{ a ...

  2. C++ 笔记(一) —— 尽量以 const、enum、inline 替换 #define

    ilocker:关注 Android 安全(新手) QQ: 2597294287 #define ASPECT_RATIO 1.653 记号 ASPECT_RATIO 不会进入 symbol tabl ...

  3. Effective C++ 之 Item 2:尽量以 const, enum, inline 替换 #define

    Effective C++ Chapter 1. 让自己习惯C++(Accustoming Yourself to C++) Item 2. 尽量以 const, enum, inline 替换 #d ...

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

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

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

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

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

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

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

    换一种说法就是宁可以编译器替换预处理器 举例 #define ASPECT_RATIO 1.653 记号ASPECT_RATIO也许从未被编译器看见:也许在编译起开始处理源码前它就被预处理器移走了,于 ...

  8. 第一篇:尽量多的以 const/enum/inline 替代 #define

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

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

    条款02: 尽量以 const, enum, inline 替换 #define 这个条款或许可以改为“宁可以编译器替换预处理器”. 编译过程: .c文件--预处理-->.i文件--编译--&g ...

随机推荐

  1. B. Lost Array

    链接 [http://codeforces.com/contest/1043/problem/B] 题意 自己点开链接看 分析 1到n枚举某个值,判断是否满足并统计 判断方法:假设x序列成立,那么后面 ...

  2. Linux内核分析第十八章读书笔记

    第十八章 调试 调试工作艰难是内核级开发区别于用户级开发的一个显著特点. 18.1 准备开始 我们需要什么? 一个bug 一个藏匿bug的内核版本 思路:假定能够让bug重现 在用户级程序中,bug直 ...

  3. visual studio-2013之单元测试

    安装个vs把一个寝室搞得欲仙欲死的,,已经安装好了vs2013,那些欲仙欲死的事就都不说了.开始我们的正式作业——单元测试. 要做单元测试前提有: 1.要有Unit Test Generator工具 ...

  4. css3-文本新增属性

    rgba:a是设透明度值 应用:background:rgb(255,255,255,0.5) color:rgb(255,255,255,0.5) border:1px solid rgb(255, ...

  5. python 如何写CMD命令工具

    #-*- coding: UTF- -*- import argparse import sys: sys.argv.append('--help') parser = argparse.Argume ...

  6. [转帖]kubeadm 实现细节

    kubeadm 实现细节 http://docs.kubernetes.org.cn/829.html 1 核心设计原则 2 常量和众所周知的值和路径 3 kubeadm init 工作流程内部设计 ...

  7. Jquery 获取屏幕及滑块及元素的高度及距离

    alert($(window).height()); //浏览器时下窗口可视区域高度 alert($(document).height()); //浏览器时下窗口文档的高度 alert($(docum ...

  8. PowerExchange实时抽取架构介绍

    工作原理 准实时抽取架构图: 以上共有核心业务系统数据库服务器.ETL服务器.BI数据库服务器[目标数据库服务器],三台服务器和ETL客户端(PowerCenter客户端).其中核心业务系统上有核心系 ...

  9. BZOJ2299 HAOI2011向量(数论)

    设最后的组成为x=x0a+x1b,y=y0a+y1b.那么容易发现x0和y0奇偶性相同.x1和y1奇偶性相同.于是考虑奇偶两种情况,问题就变为是否存在x和y使ax+by=c,那么其充要条件是gcd(a ...

  10. CodeForces - 707C

    C. Pythagorean Triples time limit per test 1 second memory limit per test 256 megabytes input standa ...