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的更多相关文章

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

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

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

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

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

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

  4. NO.2: 尽量以const,enum,inline 替换 #define

    1.首先#define 定义不重视作用域(scope),虽然可以#undef控制,但是不美观,还存在多次替换的问题,以及没有任何封装性. 2.const XXX_XX,保证其常量性以及可控的作用域,如 ...

  5. 读书笔记_Effective_C++_条款二:尽量以const, enum, inline替换#define

    其实这个条款分成两部分介绍会比较好,第一部分是用const和enum替换不带参的宏,第二部分是用inline替换带参的宏. 第一部分:用const和enum替换不带参宏 宏定义#define发生在预编 ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. uva 10453 - Make Palindrome(dp)

    题目链接:10453 - Make Palindrome 题目大意:给出一个字符串,通过插入字符使得原字符串变成一个回文串,要求插入的字符个数最小,并且输出最后生成的回文串. 解题思路:和uva 10 ...

  2. ASP.NET Web API Authorization using Tokens

    Planning real world REST API http://blog.developers.ba/post/2012/03/03/ASPNET-Web-API-Authorization- ...

  3. 使用ionic与cordova(phonegap)进行轻量级app开发前的环境配置与打包安卓apk过程记录

     前言 有人说:"如果你恨一个人,就让ta去接触cordova(phonegap)",这是因为这里面的水很深,坑很多,真让人不是一般地发狂.或许有幸运的人儿基本顺顺利利就配置完环境 ...

  4. Linux学习netstat

    netstat命令用于显示与IP.TCP.UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况.netstat是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP和UDP ...

  5. 判断浏览器 IE 11

    var getOs=function()  {   try {  var u = window.navigator.userAgent.toLocaleLowerCase(),  msie = /(m ...

  6. Android DatePicker和TimePicker

    监测日期改变的监听器:      OnDateChangedListener和OnTimeChangedListener()           当用户改变Datepicker里的年.月.日时,将触发 ...

  7. nodejs 文件查找中文,替换为英文

    帮以前同事解决一个需求,中文项目 翻译 英文项目~~~ 考虑到具体实现方面的问题,如果智能的话,肯定是要做中文的语法分析,不过感觉这个有难度. 所以最后的方案是遍历文件,将中文短语匹配出来,再进行人工 ...

  8. windows7 64位下运行 regsvr32 注册ocx或者dll的方法

    来源:转载   it won't work for you unless you have some form of Visual Basic tools loaded on your system: ...

  9. 关于RSA加密

    RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密. RSA的算法涉及三个参数,n.e1.e2. 其中,n是两个大质数p.q的积,n的二进制 ...

  10. KETTLE使用入门

    一.准备文件 1.安装java虚拟机 2.安装kettle安装文件 二.使用步骤 1.点击Spoon.bat,启动kettle,弹出DOS窗口如下: 2.进入主界面 3.新建资源库