从一个例子开始吧

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. Unity攻击敌人时产生泛白效果

    Shader的代码如下,主要是将透明度为1的像素点输出为白色,其中_BeAttack表示角色被攻击的泛白状态 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_M ...

  2. (转)OWASP ZAP下载、安装、使用(详解)教程

    OWASP Zed攻击代理(ZAP)是世界上最受欢迎的免费安全审计工具之一,由数百名国际志愿者*积极维护.它可以帮助您在开发和测试应用程序时自动查找Web应用程序中的安全漏洞. 也可以说:ZAP是一个 ...

  3. 利用十字链表压缩稀疏矩阵(c++)-- 数据结构

    题目: 7-1 稀疏矩阵 (30 分)   如果一个矩阵中,0元素占据了矩阵的大部分,那么这个矩阵称为“稀疏矩阵”.对于稀疏矩阵,传统的二维数组存储方式,会使用大量的内存来存储0,从而浪费大量内存.为 ...

  4. 利用顺序栈解决括号匹配问题(c++)-- 数据结构

    题目: 7-1 括号匹配 (30 分)   给定一串字符,不超过100个字符,可能包括括号.数字.字母.标点符号.空格,编程检查这一串字符中的( ) ,[ ],{ }是否匹配. 输入格式: 输入在一行 ...

  5. Delphi中 弹出框的用法

    Delphi中的提示框有 Application.MessageBox  ShowMessage messagedlg 个人认为 相对来说 Application.MessageBox 更加灵活 也相 ...

  6. 《Linux内核分析》第五周

    20135103王海宁 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 这周的实验在上周实验四的基础上, ...

  7. Linux内核分析课程期中总结

    Linux内核分析课程期中总结 姓名:王朝宪 学号:20135114 注: 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com ...

  8. 20135316王剑桥Linux内核学习笔记第四周

    20135316王剑桥 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC 1000029000 1.内核态:在高执行级别,代码可 ...

  9. 读C#程序最小公倍数答案就是:2123581660200

    阅读下面程序,请回答如下问题: 问题1:这个程序要找的是符合什么条件的数? 问题2:这样的数存在么?符合这一条件的最小的数是什么? 问题3:在电脑上运行这一程序,你估计多长时间才能输出第一个结果?时间 ...

  10. Win2008r2 由ESXi 转换到 HyperV的处理过程

    1. 大部分2008r2 采取了 windows loader的方式激活 这种方式 会导致hyperV 启动失败 因为他家在了错误的bios类型 所以第一步建议 使用windows loader 卸载 ...