ilocker:关注 Android 安全(新手) QQ: 2597294287

 #define ASPECT_RATIO  1.653

记号 ASPECT_RATIO 不会进入 symbol table,因为它在预处理阶段就被替换了。

如果运用此常量时获得了一个编译错误,并且该宏定义又非自己所写,就会对 1.653 为何意、来自何处而感到困惑。于是,我们会因为追踪代码而浪费时间。

应以常量取而代之:

 const double kAspectRatio = 1.653;

这样没准还会减小 object code 的体积,因为预处理器“盲目”的进行宏替换,可能会导致多份 1.653。

如果要定义一个常量的 char * 字符串,则:

 const char * const kAuthorName = “Scott Meyers”;

两个 const,一个约束字符串内容不可变,一个约束字符串指针不可变。

或者这样:

 const std::string kAuthorName(“Scott Meyers”);

另外,宏没有作用域的限制,也不能提供任何封装性,但 const 常量可以。

 class GamePlayer {
private:
static const int kNumTurns = ;
int scores[kNumTurns];
}

然后在定义文件中:

 const int GamePlayer::kNumTurns;

如果不是在数组声明中用到了 kNumTurns,其初值的设定也可以放到定义中。

如果编译器不支持 in-class 初值设定,也可用所谓的 “the enum hack” 手法:

 class GamePlayer {
private:
enum { kNumTurns = };
int scores[kNumTurns];
}

也许对于此种应用,enum hack 的方式更好。enum hack 的行为更相像于 #define,因为对于一个 enum 值,同样不能取其地址。

#define 的另一个常见用处是定义一个“伪函数”,而调用它不会招致 function call 带来的额外开销。

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

定义这种宏要十分小心,每个实参都要加上小括号,但仍应对不了下述情况:

 CALL_WITH_MAX(++a, b); //a可能会被累加两次

这种情况下,可以 template inline 函数代之:

 template<typename T>
inline void CallWithMax(const T &a, const T &b) {
f(a > b ? a : b);
}

最后,#define 也许只需用于防止头文件的重复 include。

学习资料: 《Effective C++》

C++ 笔记(一) —— 尽量以 const、enum、inline 替换 #define的更多相关文章

  1. Effective C++阅读笔记_条款2:尽量以const,enum,inline替换#define

    1.#define缺点1 #define NUM 1.2 记号NUM可能没有进入记号表,在调试或者错误信息中,无法知道1.2的含义. 改善:通过const int NUM = 1.2; 2.#dein ...

  2. Effective C++学习笔记 条款02:尽量以const,enum,inline替换 #define

    尽量使用const替换 #define定义常量的原因: #define 不被视为语言的一部分 宏定义的常量,预处理器只是盲目的将宏名称替换为其的常量值,导致目标码中出现多分对应的常量,而const定义 ...

  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. 条款2:尽量以const, enum, inline替换#define

    原因: 1. 追踪困难,由于在编译期已经替换,在记号表中没有. 2. 由于编译期多处替换,可能导致目标代码体积稍大. 3. define没有作用域,如在类中定义一个常量不行. 做法: 可以用const ...

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

    目录 1. 总结 2. 使用const常量或enum替换宏常量 class外部的常量指针 class专属常量 1. 总结 对于单纯常量,最好以const常量或enum替换#define 对于宏代码段, ...

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

    class GamePlayer{private: static const int NumTurns = 5; int scores[NumTurns]; ...}; 万一你的编译器(错误地)不允许 ...

  8. 条款2:尽量使用const ,enum,inline替换define

    宁可使用编译器而不用预处理器 假设我们使用预处理器: #define ABC 1.56 这标识符ABC也许编译器没看到,也许它在编译器处理源码前就被预处理器移走了,于是“标识符”ABC没有进入标识符列 ...

  9. Effective C++之条款2:尽量以const enum inline替换 #define

    本文的标题也可以改成“用编译器替换预处理器”: const double AspectRatio = 1.653; //最好使用上述代码替换下述代码: #define ASPECT_RATIO 1.6 ...

  10. Book. Effective C++ item2-尽量使用const, enum, inline替换#define

    ##常规变量 c++里面的#define后面的定义部分,是不算代码的一部分的.所以如果你使用#define: #define ASPECT_RATIO 1.653 你希望这个代号ASPECT RATI ...

随机推荐

  1. CI框架源码阅读笔记8 控制器Controller.php

    最近时间有些紧,源码阅读系列更新有些慢.鉴于Controller中代码比较少,本次Blog先更新该文件的源码分析. 在经过路由分发之后,实际的应用Controller接管用户的所有请求,并负责与用户数 ...

  2. svn利用钩子实现代码同步到web目录

    思路:  找 到SVN Server中的仓库(Repositories)文件夹的位置,在相应的项目文件夹中找到hooks文件夹.在该文件夹中添加一个post- commit文件:当有commit动作发 ...

  3. IO流(五)__文件的递归、Properties、打印流PrintStream与PrintWriter、序列流SequenceInputStream

    一.文件的遍历 1.需求:对指定目录进行所有的内容的列出(包含子目录的内容)-文件的深度遍历 思想:递归的思想,在递归的时候要记住递归的层次. public class FileTest { publ ...

  4. VS Code前端开发利器-常用快捷键

    1.Ctrl+N ,新建文件,新建文件后需要先进行保存(Ctrl+S)并设置文件扩展名: 2.! +Tab,快速创建H5框架,文件扩展名必须为html: 3.Ctrl+Shift+P ,调出命令列表, ...

  5. 移动 Web 开发必备!时尚的 Off Canvas 导航

    这里向大家分享一组创新的 Off Canvas 导航效果.Off Canvas 导航在一些移动应用程序中被广泛使用.当你点击汉堡按钮(一般是三条横线组成)时,在左侧或者右侧拉出一个菜单,这样可以充分利 ...

  6. MySQL之MySQL5.7安装包(msi文件)在Windows8下安装

    最近自己在使用MySQL5.7.16.msi安装MySQL.自己下载的是.msi文件,在安装的过程中遇到了许多文件,网上大部分的Blog都是关于免安装包的安装方法,希望我的方法对大家有帮助. 1,下载 ...

  7. vueJS简单的点击显示与隐藏的效果

    目前前端框架太多,接触过angular.ember,现在开始倒腾vue 此处用到v-if.v-else.v-show,v-if或让元素不在DOM上,v-show只是改变display:block属性, ...

  8. CodeIgniter_2 路由中定义伪静态 直接映射到相关的控制器

    某些情况下 隐藏路径信息 使用伪静态定义: RewriteRule ^no/torrent(.*)$ /index.php/torrent/doit/$1 CodeIgniter会自动识别到 no 控 ...

  9. 在 SharePoint 2013 中选择正确的 API 集

    决定使用哪个 API 集的因素   您可以在多个 API 集中选择一个来访问 SharePoint 2013 平台.您使用哪一个 API 集取决于以下因素: 应用程序的类型. 可能的类型包括但不限于以 ...

  10. sharepoint 权限继承相关

    重新继承父级权限: SPList.ResetRoleInheritance(); 断开继承: SPList.BreakRoleInheritance(true); 用powershell断开继承: $ ...