Effective C++(1-2) 编译器替换预处理器
- C
- Object-Oriented C++: 面向对象
- Template C++:泛型编程
- STL
#define ASPECT_RATIO 1.653记号名称ASPECT_RATIO在被编译器识别之前,已经被预编译器替换为1.653了,所以名称ASPECT_RATIO有可能没进入记号表内。解决方法:
const double AspectRatio = 1.653;
性能影响:对浮点常量而言,使用常量可能币使用#define导致较小量的码,因为预处理“盲目地将宏名称ASPECT_RATIO”替换为1.653。
2.2 关于const的一个知识点
若要定义一个char*字符串,必须写const两次
const char* const authorName = "Scott Meyers";
若替换为String对象则更好:
const std::string authorName("Scott Meyers");
2.3 class专属常量
static, 将常量的作用域限制于class内,且确保此常量至多只有一份实体。class GamePlayer {
private:
static const int NumTurns = 5; //常量声明式
int scores[NumTurns]; //使用该常量
};
这里的NumTurns是个声明式,而不是定义式。一般情况下,这样做就足够了,声明并使用它,但是有两种情况需要你给出一个关于它的定义式:1 取这个class专属常量的地址2 编译器坚持要看到一个定义式这时候就需要一个额外的定义式:const int GamePlayer::NumTurns; // 由于class常量已在声明时或得初值,因此定义时不可以再设初值。如果旧式的编译器不支持“in-class 初值设定”,那么可以把初值的设定放在定义式中:class CostEstimate {
private:
static const double FudgeFactor;
...
};
ConstEstimate::FudgeFactor = 1.35; // 位于实现文件内
如果你的编译器不够优秀,不允许"static整数型class常量"完成“in class初值设定”,那么,就有必要认识一下enum hack。先看一下补偿的做法:
class GamePlayer {
private:
enum { EnumTurns = 5 };
int scores[NumTurns];
};
现在来正式认识一下enum hack:
1 enum hack的行为某些方面比较像#define而不是const,如:
- 取一个enum的地址是不合法的,同样的,取一个#define的地址通常也不合法;
- 不允许一个指针或者引用指向某个enum常量;
- Enums和#defines绝不会导致非必要的内存分配。
2 实用主义: 事实上,“enum hack”是template metaprogramming(模版元编程)的基础技术。
// 以a和b的较大值调用f
#define CALL_WITH_MAX(a, b) f ( (a) > (b) ? (a) : (b) )
纵使我是一个很有耐心的人,但是有时候遇到更复杂的宏的时候也会有点抓狂。
需要铭记一件事就是,宏是一个经常出现不可思议的事情:
int a = 5, b = 0;
CALL_WITH_MAX( ++a, b ); // a被累加两次
CALL_WITH_MAX( ++a, b+10 ); // a被累加一次
神奇的事情就是,a的递增次数取决于“它被拿来和谁比较”。
解决办法: template inline函数
template<typename T>
inline void callWithMax(const T& a, const T& b)
{
f ( a > b ? a : b);
}
- 对于单纯常量,最好以const对象或者enum替换#define
- 对于形似函数的宏, 最好改用inline函数替换#define
Effective C++(1-2) 编译器替换预处理器的更多相关文章
- Effective C++ 条款二 用编译器替换预编译器
/************************************************************************/ /* C++条款二:用编译器替换预编译器 */ / ...
- [Objective-C语言教程]预处理器(18)
Objective-C预处理器不是编译器的一部分,而是编译过程中的一个单独步骤. 简单来说,Objective-C预处理器只是一个文本替换工具,它指示编译器在实际编译之前进行必要的预处理. 我们将Ob ...
- C语言笔记 10_文件读写&预处理器
文件读写 上一章我们讲解了 C 语言处理的标准输入和输出设备.本章我们将介绍 C 程序员如何创建.打开.关闭文本文件或二进制文件. 一个文件,无论它是文本文件还是二进制文件,都是代表了一系列的字节.C ...
- C和指针 第十四章 预处理器 头文件
编写一个C程序,第一个步骤称为预处理,预处理在代码编译之前,进行一些文本性质的操作,删除注释.插入被include的文件.定义替换由#define定义的符号,以及确定代码的部分内容是否应该按照条件编译 ...
- 详解C/C++预处理器
C/C++编译系统编译程序的过程为预处理.编译.链接.预处理器是在程序源文件被编译之前根据预处理指令对程序源文件进行处理的程序.预处理器指令以#号开头标识,末尾不包含分号.预处理命令不是C/C++语 ...
- C Primer Plus之C预处理器和C库
编译程序前,先由预处理器检查程序(因此称为预处理器).根据程序中使用的预处理器指令,预处理器用符号缩略语所代表的内容替换程序中的缩略语. 预处理器不能理解C,它一般是接受一些文件并将其转换成其他文本. ...
- C和指针 (pointers on C)——第十四章:预处理器
第十四章 预处理器 我跳过了先进的指针主题的章节. 太多的技巧,太学科不适合今天的我.但我真的读,读懂.假设谁读了私下能够交流一下.有的小技巧还是非常有意思. 预处理器这一章的内容.大家肯定都用过.什 ...
- CSS 预处理器中的循环
本文由 nzbin 翻译,黄利民 校稿.未经许可,禁止转载! 英文出处:css-tricks.com 发表地址:http://web.jobbole.com/91016/ 如果你看过老的科幻电影,你一 ...
- Microsoft Visual C++ 6.0预处理器参考手册
返回总目录 Microsoft Visual C++ 6.0 预处理器参考手册 目录引言........................................................ ...
随机推荐
- 创建自己的加密货币MNC——以太坊代币(二)
创建一个基于以太坊平台的分红币MNC,根据持有的代币数量,进行分红的算法.github地址: https://github.com/lxr1907/MNC 1.使用以太坊根据比例换购token MNC ...
- Git提交项目到GitHub
一.GitHub新建项目 1.进入Github首页,点击New repository新建一个项目 2.填写相应信息后点击create即可 Repository name: 仓库名称 Descripti ...
- 《LeetBook》leetcode题解(7): Reverse Integer[E]——处理溢出的技巧
我现在在做一个叫<leetbook>的开源书项目,把解题思路都同步更新到github上了,需要的同学可以去看看 书的地址:https://hk029.gitbooks.io/leetboo ...
- STL 排序(转载)
这篇文章关于STL中的排序写的虽不深入,但是还是挺好的. 1.sort sort有两种形式,第一种形式有两个迭代器参数,构成一个前开后闭的区间,按照元素的 less 关系排序:第二种形式多加一个指定排 ...
- js处理json数据,java处理json数据
一.js处理json数据 处理办法之一是把本机json数据或远程返回json数据用eval函数,使之变成DOM对象. 例如: var people = { "programmers" ...
- 码表的理解(ASCII,GBK,Unicode,UTF-8等)。
以下任何言论都完全是个人的理解,如有雷同纯属巧合,如有错误,希望大家多多指出,共同学习!谢谢! 笔者是一个理解能力偏慢.稍钻牛角尖的程序员,什么东西都要从最基础理解起,一步一步向上理解,因此讲述时也是 ...
- C#中获取各种路径获取方法
// 获取程序的基目录.System.AppDomain.CurrentDomain.BaseDirectory // 获取模块的完整路径,包含文件名System.Diagnostics.Proces ...
- Python——基本的书写规则
1.输入方法input() 等待用户输入数据,并回车后得到数据(name为输入的字符串) name=input('Please input your name:') print('Hi,',name) ...
- [转] 如何应用设计模式设计你的足球引擎(一和二)----Design Football Game(Part I and II)
原文地址: http://www.codeproject.com/KB/architecture/applyingpatterns.aspx 作者:An 'OOP' Madhusudanan 译者:赖 ...
- msql查询指定日期
今天 select * from 表名 where to_days(时间字段名) = to_days(now()); 昨天 SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ...