1 C++最主要的四部分:
  1. C
  2. Object-Oriented C++: 面向对象
  3. Template C++:泛型编程
  4. STL
C++高效编程守则视状况而变化,取决于你使用C++的哪一部分。
2 尽量以const, enum , inline替换 #define
2.1

#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; // 位于实现文件内
2.4 enum hack

如果你的编译器不够优秀,不允许"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(模版元编程)的基础技术。

2.5 形似函数的宏——>template inline函数

// 以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++ 3rd》

Effective C++(1-2) 编译器替换预处理器的更多相关文章

  1. Effective C++ 条款二 用编译器替换预编译器

    /************************************************************************/ /* C++条款二:用编译器替换预编译器 */ / ...

  2. [Objective-C语言教程]预处理器(18)

    Objective-C预处理器不是编译器的一部分,而是编译过程中的一个单独步骤. 简单来说,Objective-C预处理器只是一个文本替换工具,它指示编译器在实际编译之前进行必要的预处理. 我们将Ob ...

  3. C语言笔记 10_文件读写&预处理器

    文件读写 上一章我们讲解了 C 语言处理的标准输入和输出设备.本章我们将介绍 C 程序员如何创建.打开.关闭文本文件或二进制文件. 一个文件,无论它是文本文件还是二进制文件,都是代表了一系列的字节.C ...

  4. C和指针 第十四章 预处理器 头文件

    编写一个C程序,第一个步骤称为预处理,预处理在代码编译之前,进行一些文本性质的操作,删除注释.插入被include的文件.定义替换由#define定义的符号,以及确定代码的部分内容是否应该按照条件编译 ...

  5. 详解C/C++预处理器

     C/C++编译系统编译程序的过程为预处理.编译.链接.预处理器是在程序源文件被编译之前根据预处理指令对程序源文件进行处理的程序.预处理器指令以#号开头标识,末尾不包含分号.预处理命令不是C/C++语 ...

  6. C Primer Plus之C预处理器和C库

    编译程序前,先由预处理器检查程序(因此称为预处理器).根据程序中使用的预处理器指令,预处理器用符号缩略语所代表的内容替换程序中的缩略语. 预处理器不能理解C,它一般是接受一些文件并将其转换成其他文本. ...

  7. C和指针 (pointers on C)——第十四章:预处理器

    第十四章 预处理器 我跳过了先进的指针主题的章节. 太多的技巧,太学科不适合今天的我.但我真的读,读懂.假设谁读了私下能够交流一下.有的小技巧还是非常有意思. 预处理器这一章的内容.大家肯定都用过.什 ...

  8. CSS 预处理器中的循环

    本文由 nzbin 翻译,黄利民 校稿.未经许可,禁止转载! 英文出处:css-tricks.com 发表地址:http://web.jobbole.com/91016/ 如果你看过老的科幻电影,你一 ...

  9. Microsoft Visual C++ 6.0预处理器参考手册

    返回总目录 Microsoft Visual C++ 6.0 预处理器参考手册 目录引言........................................................ ...

随机推荐

  1. 运行零币Zcash(ZEC)

    1.在基于 Ubuntu 或者 Debian 的系统中: $ sudo apt-get install \build-essential pkg-config libc6-dev m4 g++-mul ...

  2. 【转发】Webdriver使用自定义Firefox Profile运行测试

    点击进入转发地址: 一般我们使用如下代码启动Firefox: 这样Selenium Server启动的Firefox将是一个全新的,不安装任何Add-On的Firefox. 如果有需要,我们可以使用我 ...

  3. Jquery 在多个相同标签click的问题

    最近在做文章的删除动作,用Jquery来执行操作.但是实现时一开始总是只能对第一个起作用,其他的点击删除后没反应. 一开始的jquery代码是这样的, $('#articledelete').on(' ...

  4. 【转】WinForm窗体显示和窗体间传值

    以前对WinForm窗体显示和窗体间传值了解不是很清楚 最近做了一些WinForm项目,把用到的相关知识整理如下 A.WinForm中窗体显示 显示窗体可以有以下2种方法: Form.ShowDial ...

  5. vue中$watch源码阅读笔记

    项目中使用了vue,一直在比较computed和$watch的使用场景,今天周末抽时间看了下vue中$watch的源码部分,也查阅了一些别人的文章,暂时把自己的笔记记录于此,供以后查阅: 实现一个简单 ...

  6. 从零开始学JAVA(08)-使用SpringMVC4 Restful 风格引用静态文件 css/js/png

    在写完helloworld后想给网页加点样式(*.css),结果怎么也显示不了,百度了很多种方法后试行尝试,试验成功并记录下来,方便以后查看. 时隔两年,继续学习JAVA,太久没学了,忘记得差不多,还 ...

  7. nodejs应用离线安装部署、卸载

    公司写的文档,直接粘贴过来了: 本文档提供node应用一键安装.部署.卸载说明,包含对应脚本文件 默认版本:1.nodejs:v6.11.2.linux-x642.全局npm包:pm2.supervi ...

  8. 一、Java多线程基础

    一.简介 1.操作系统 在早起的裸机时代,计算机非常地昂贵,而且也没有操作系统的概念,计算机从头到尾只能执行一个程序.如果程序在执行一个耗时的操作,那么在这个过程中,计算机就有大量的资源闲置在那里,这 ...

  9. java技术秘籍 转摘

  10. Java基础之JDK的下载与安装

    做Java开发已经很长一段时间了,最近在回顾Java的基础知识,感觉好多都是知道这个概念,能说个皮毛,但是往深了说又不知道怎么说,所以打算对Java从头做一个回顾,算是对自己所学知识的一个巩固和深入了 ...