笔记:Perfer consts,enums,and inlines to #define
来源:互联网 发布:淘宝开店装修教程视频 编辑:程序博客网 时间:2024/05/16 06:55
#define 或许不被视为语言的一部分。
#define ASPECT_RATIO 1.63
ASPECT_RATIO也许从未被编译器看见,也许在编译器开始处理源码之前就被预处理器移走了。
于是ASPECT_RATIO有可能没有进入符号表(symbol table).
要是出现错误就不好调试。
可能出现两个错误,错误信息说1.63而不是ASPECT_RATIO。或者这个定义出现在另外的头文件,出现这个错误可能在符号调试器中(symbolic debugger),但是因为ASPECT_RATIO不在符号表中出现错误。
解决的办法是用常量代替上述的宏(#define)
const double AspectRatio = 1.63
//大写名称通常用于宏,这里是变量。
作为一个常量,AspectRatio肯定会被编译器看见,也就会进入符号表内。
此外对浮点常量(floating point constant)而言,使用常量可能比使用#define导致较小量的码,因为预处理会盲目将宏ASPECT_RATIO替换成1.63,导致目标码(object code)出现多份1.63,若改用常量就不会出现这样的情况。
当使用常量替换#define,有两种特殊的情况.
1,定义常量指针(constant pointers)
由于常量定义式通常被放在头文件内让不同的源代码使用,因此有必要对指针(不仅仅是指针所指向的对象)声明为const。(防止被改动)
例如若要在头文件定义一个常量的基于char*的字符串,必须写const两次:
const char* const authorName = "Scott Meyers";
关于const的意义和使用(特别是与指针结合时),在条款3有详细的讨论。
string对象通常比char*-based 合适,所以下面定义更好:
const std::string authorName= "Scott Meyers";
2,class专属常量。
若要使某个常量的作用域(scope)限制于class内,必须让它成为class的一个成员。
若是要使这个常量只有一份实体,就必须让其是static成员。
class GamePlayer
{
private:
static const int NumTurns = 5; //这个表达式是常量声明式,非定义式。
int scores[NumTurns]; // 使用了该常量
。。。
};
C++要求你对你所使用的任何变量都提供一个定义式,如果它是class的专属常量,还是static的,并且类型为整数类型(integral type,例如int,char,bool),要特殊处理。只要不取他们的地址,可以只声明并且使用而不需要再提供一个定义式。
若是要取class专属常量的地址就必须提供一个定义式
const int GamePlayer::NumTurns; //NumTurns的定义式。为什么没有赋值了?
这个定义式放在CPP文件中,由于class常量在声明时候已经获得初值,因此定义时不需要再设初值。
在VS 2005中要是提供了定义式则会出现重复定义的错误。
用G++编译器则是对的。
不过一般旧的编译器也是不支持以上的语法,不允许static成员在其声明式上获得初值。则只有把初值放在定义式中。
比如
class CostEstimate
{
private:
static const double FudgeFactor; //static const 常量声明 位于头文件
};
const double CostEstimate::FudgeFactor = 2.33; //static const 常量定义位于实现文件内(cpp文件)
再就是在类中(in-class)的初值设定也只允许对整数常量进行,其他的数据类型必须在定义式中进行赋初值。
有一种例外就是当class编译期间需要一个class的常量值,就需要一种补偿的做法。
比如说class GamePlayer中的score的数组声明式中必须要知道其大小。编译器不允许static整数型class常量 完成的在类中的初值设定,就可以改用“the enum hack”补偿做法。
这个的理论基础是:“一个属于枚举类型的数值可以权充int被使用”,于是GamePlayer可以定义如下:
class GamePlayer
{
private:
enum {NumTurns = 5}; //the enum hack --- 令NumTurns成为5的一个记号名称
int scores[NumTurns];
。。。
};
基于一些理由enum hack值得我们了解。
1, enum hack的行为某方面比较像 #define而不像 const,有时候这样就是你所想要的。取const的地址是合法,去enum就不合法。如果你不想别人活着一个指针或引用指向你的某个整数变量,enum是个好的选择,实现了这个约束。(条款18讲解了“通过撰写代码来实施设计上的约束条件”)。
2,Effective C++上说是为了实用主义。许多代码用了它,所以应该了解。 事实上“enum hack”是template metaprogramming(模板元编程,48)的基础技术。
最后用inline代替宏函数。(条款30详细说明inline函数)
记住:
1,对于单纯常量,最好以const对象活着enum替换 #define
2,对于形似函数的宏,最好改用inline函数替换 #difine
- 笔记:Perfer consts,enums,and inlines to #define
- 条款02:尽量以const, enum, inline替换#define(Prefer consts,enums, and inlines to #defines)
- Item 02 : Prefer consts, enums, and inlines to #defines
- Item 02: Prefer consts, enums, and inlines to #defines
- Effective C++ 2. Prefer consts, enums, and inlines to #defines
- Effective C++ Item 2:Prefer constS, enumS, and inlineS to #defineS
- effective C++ Item 2: Prefer consts, enums, and inlines to #defines
- Effective C++读书笔记(3)-Item 2: Prefer consts, enums, and inlines to #defines
- Effective C++读书笔记——(一)Prefer consts, enums, and inlines to #defines
- 《Effctive C++》读书笔记--(02)Prefer consts,enums,and inlines to #defines
- Effective C++ (3rd Ed) 读书笔记(一)Item 2: Prefer constS, enumS, and inlineS to #defineS
- Effective C++----3rd Edition, Item 2:用consts,enums和inlines取代#define
- [翻译] Effective C++, 3rd Edition, Item 2: 用 consts, enums 和 inlines 取代 #defines
- Effective C++,rule 2,Prefer const,enum and inlines to #define
- Consts and Fields
- Item21 Perfer std::make_unique and std::make_shared to direct use of new
- How to cast enums which are using QFlags and QList?
- Item10 Prefer scoped enums to unscoped enums
- 开博啦!
- hdu1016Prime Ring Problem解题报告
- 深拷贝&&浅拷贝
- 我的开题困惑
- hdu1379DNA Sorting解题报告
- 笔记:Perfer consts,enums,and inlines to #define
- [转]Win7的30个技巧
- Python监视进程
- 在ASP.NET 中实现单点登录
- 清理GIF恶意代码IFRAME好用工具,GIF代码查找替换批量删除工具(Trojan.DL.Giframe.a引起)
- 时间同步问题
- 与黑客相关
- WSAEventSelect()功能描述
- __iob符号 找不到