《Effective C++》Item2:尽量以const,enum,inline替换#define
1. 宏定义
#define ASPECT_RATIO 1.653
该宏定义ASPECT_RATIO也许从来没有被编译器看到,也许在编译器开始处理源码之前就已经被预处理器替换了。所以记号名称ASPECT_RATIO有可能没进入符号表(symbol table)中。所以,当你从这个常量得到一个编译错误信息时,这个错误信息可能会提到1.653而不是ASPECT_RATIO,如果这个ASPECT_RATIO被定义在一个非你写的头文件中,那么调试追踪这个错误更是麻烦。在调试阶段,visual stiduo和linux平台的gdb在调试的过程中无法查找定义的宏的值,因为符号表中没有这个符号,因此不能所见即所得,还必须通过阅读代码才能看到。
2. 使用const定义常量
解决上面的问题的办法就是,以一个常量替换上面的宏
const double aspectRatio = 1.653;//大写名称通常用于宏,因此这里改变名称写法
从上面可以看出该常量有类型,double。它作为一个常量,肯定能被编译器看到,当然也就能进入符号表中了,进入了符号表的常量表中。
3. class专属常量
为了将常量的scope限制于class内,就必须让它成为class的一个成员;而为了确保此常量最多只有一份实体,必须让他让成为一个static成员。
class GamePlayer
{
private:
static const int NumTurns = 5;//常量声明式
int scores[NumTurns];//使用该常量
};
这里看到的是NumTurns的声明式而非定义式。通常C++要求对所使用的任何东西提供一个定义式,但如果它是个class专属常量又是static且为整数类型(integral type例如ints、chars、bools),则需要特殊处理。只要不取他们的地址,就可以声明并使用他们而无需提供定义式。如果要取某个class专属常量的地址,就必须提供这个专属常量的定义式:
const int GamePlayer::NumTurns;//NumTurns的定义
要把这个statement放进一个实现文件而非头文件,同时由于class常量在声明时获得了初值,定义时就不可以再设置初值了。
下面在举个例子说明用法:
class MyTest
{
//“MyTest::maxNumber1”: 只有静态常量整型数据成员才可以在类中初始化
//int maxNumber1 = 5; //“MyTest::maxNumber1”: 只有静态常量整型数据成员才可以在类中初始化
//const int maxNumber2 = 5; //“MyTest::maxNumber1”: 只有静态常量整型数据成员才可以在类中初始化
//static int maxNumber3 = 5; static const int maxNumber4 = 5;
static const char cconst = 'A';
public:
//“MyTest::maxNumber2”: 必须在构造函数基/成员初始值设定项列表中初始化
//如果有const常量成员,一定要在构造函数的初始值设定项列表中初始化
MyTest()
{
cout << "MyTest Constructor!" << endl;
cout << "maxNumber4 = " << maxNumber4<< endl;
cout << "cconst4 = " << cconst << endl;
} };
总结一下:
对于类的const类型的成员,一定要在构造函数的初始化列表中初始化,不管这个const成员变量是static还是非static的。
对于static的成员变量,要在.cpp文件中提供一个定义式。对静态成员变量的初始化就在这个定义式中进行,但是后面可以在构造函数等的地方做修改。
《Effective C++》Item2:尽量以const,enum,inline替换#define的更多相关文章
- Book. Effective C++ item2-尽量使用const, enum, inline替换#define
##常规变量 c++里面的#define后面的定义部分,是不算代码的一部分的.所以如果你使用#define: #define ASPECT_RATIO 1.653 你希望这个代号ASPECT RATI ...
- Effective C++阅读笔记_条款2:尽量以const,enum,inline替换#define
1.#define缺点1 #define NUM 1.2 记号NUM可能没有进入记号表,在调试或者错误信息中,无法知道1.2的含义. 改善:通过const int NUM = 1.2; 2.#dein ...
- Effective C++学习笔记 条款02:尽量以const,enum,inline替换 #define
尽量使用const替换 #define定义常量的原因: #define 不被视为语言的一部分 宏定义的常量,预处理器只是盲目的将宏名称替换为其的常量值,导致目标码中出现多分对应的常量,而const定义 ...
- NO.2: 尽量以const,enum,inline 替换 #define
1.首先#define 定义不重视作用域(scope),虽然可以#undef控制,但是不美观,还存在多次替换的问题,以及没有任何封装性. 2.const XXX_XX,保证其常量性以及可控的作用域,如 ...
- 读书笔记_Effective_C++_条款二:尽量以const, enum, inline替换#define
其实这个条款分成两部分介绍会比较好,第一部分是用const和enum替换不带参的宏,第二部分是用inline替换带参的宏. 第一部分:用const和enum替换不带参宏 宏定义#define发生在预编 ...
- 条款2:尽量以const, enum, inline替换#define
原因: 1. 追踪困难,由于在编译期已经替换,在记号表中没有. 2. 由于编译期多处替换,可能导致目标代码体积稍大. 3. define没有作用域,如在类中定义一个常量不行. 做法: 可以用const ...
- 条款02:尽量以const,enum,inline替换#define
目录 1. 总结 2. 使用const常量或enum替换宏常量 class外部的常量指针 class专属常量 1. 总结 对于单纯常量,最好以const常量或enum替换#define 对于宏代码段, ...
- Effective C++ -----条款02:尽量以const, enum, inline替换 #define
class GamePlayer{private: static const int NumTurns = 5; int scores[NumTurns]; ...}; 万一你的编译器(错误地)不允许 ...
- Effective C++之条款2:尽量以const enum inline替换 #define
本文的标题也可以改成“用编译器替换预处理器”: const double AspectRatio = 1.653; //最好使用上述代码替换下述代码: #define ASPECT_RATIO 1.6 ...
- 条款2:尽量使用const ,enum,inline替换define
宁可使用编译器而不用预处理器 假设我们使用预处理器: #define ABC 1.56 这标识符ABC也许编译器没看到,也许它在编译器处理源码前就被预处理器移走了,于是“标识符”ABC没有进入标识符列 ...
随机推荐
- 13-7-1 做了一个360优化大师的主页(就是一个主页UI)
模仿360优化大师做了一个下它的首页. 代码如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/re ...
- POJ3253 Fence Repair(贪心)
分割木板的顺序是自由的,所以每次选择两块最短的板,组合在一起,增加队列,原来两个板出队,直到队列中为空或者仅仅剩下一个板时结束.这里使用优先队列较为方便. #include<iostream&g ...
- DOM注意事项(八):JavaScript操作环境和垃圾收集
一.运行环境 在约JavaScript对象或this当指向问题,念就是运行环境.即上下文环境.运行环境在JavaScript是一个非常重要的概念.由于它定义了变量或函数有权訪问的其他数据,决定了它们各 ...
- 排颜色问题——数组 leetcode lintcode
问题描写叙述: 给一个数组,而且数组里面元素的值仅仅可能是0,1,2,然后如今把这个数组排序. 第二种表述: 现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换随意两个球,使得从左至右, ...
- 基于jQuery实现的水平和垂直居中的div窗口
在建立网页布局的时候,我们经常会面临一个问题,就是让一个div实现水平和垂直居中,虽然好几种方式实现,但是今天介绍时我最喜欢的方法,通过css和jQuery实现. 1.通过css实现水平居中: 复 ...
- 第二章SignalR所支持的平台
第二章SignalR所支持的平台 SignalR支持各种服务器和客户端的配置.此外,每种传输方式都有自身的配置要求和限制:如果某种传输方式不被系统支持,SignalR优雅地将故障转移到其他类型的传输方 ...
- Maven命令行创建web项目,并部署到jobss当中(解决No plugin found for prefix 'jboss-as' in the current project and in the plugin groups [org.apache.maven.plugins,问题)
首件创建项目:此处可参照:http://maven.apache.org/guides/mini/guide-webapp.html mvn archetype:generate -DgroupId= ...
- 20160125--Spring
package com.hanqi; import java.util.*; import com.hanqi.User; public class HelloWorld { public Hello ...
- 【codevs】2292图灵机游戏
题 Shadow最近知道了图灵机是什么(Shadow:就是一行格子和一个机器头移来移去的呗!),于是他突发奇想,创造了一个新游戏——“图灵机游戏”(Shadow:好听吧?). 游戏规则如下: 在一条长 ...
- 浅谈C中的指针和数组(五)
前面写了一些C指针和数组的一些知识,但是还有一些很重要的知识没有交代,这里做一个补充. 首先看一下,普通变量(指针也是变量)和数组名查看地址的方式是不同的. 查看数组变量的地址,不需要使用 & ...