EC笔记,第一部分:2.尽量以const,enum,inline代替#define
02.尽量以const,enum,inline代替#define
原因:编译前的预处理会替换宏,所以调试的时候找不到错误
1.const
尽量用const替代常量宏定义
两种特殊情况:
(1).常量指针
通常定义为const char * const cstr="hello world";
即要把指针本身定义为const,而不仅仅是指针指向的值,通常用string替代char*-based:
const string str("hello world");
(2).class专属常量
为了确保const成员只有一个实体,通常使用static将其声明为静态常量,但是在类中的声明仅仅是声明,类中不存在定义,即使形如:
class MyClass{//头文件中
public:
static const int t=5;//仅仅是声明
int arr[t];//可以使用该常量
};
//源文件中(实现文件中)
const int MyClass::t;//此处是定义,因为在声明的时候已经赋值,所以在此处不可赋值
如果只声明而不定义,那么对该成员无法取地址,如果没有需要取地址的操作,可以只声明不定义(仅适用于ints类型(如int,char,bool)),但是对于非整数型数据,定义式必须存在(C++11不适用,C++11已经支持在类内部赋值),即:
class MyClass{//头文件中
public:
//static const double t=5.1;//错误,类中不可赋值(非C++11)
static const double t;
int arr[t];//可以使用该常量
};
//源文件中(实现文件中)
const double MyClass::t=5.1;//此处是定义,必需
2.enum
假设你的编译器不支持在类中如此声明:static const int t=5;但是你确实在编译时需要一个整形常量,那么可以用enum{t=5};
enum更接近于#define,例如,你可以取一个const的地址,但是不能取enum的地址,当然#define的常量也不可取地址
事实上,enum是模板元编程的基础技术
3.inline
将宏定义为像一个函数通常是让你陷入到调试漩涡中的一个重要原因,所以,尽量不要将宏定义为一个函数形式(事实上,应该尽量避免使用宏),宏只是机械式的替换,而不做类型检查等工作,而且宏的参数如果是一个表达式,错误的风险将会增加,而通过模板与内联(template,inline)可以解决这些棘手的问题
总结:对于单纯常量,使用const与enum代替宏,对于函数形式的宏,则使用inline与template替代
EC笔记,第一部分:2.尽量以const,enum,inline代替#define的更多相关文章
- Effective C++学习笔记 条款02:尽量以const,enum,inline替换 #define
尽量使用const替换 #define定义常量的原因: #define 不被视为语言的一部分 宏定义的常量,预处理器只是盲目的将宏名称替换为其的常量值,导致目标码中出现多分对应的常量,而const定义 ...
- 读书笔记_Effective_C++_条款二:尽量以const, enum, inline替换#define
其实这个条款分成两部分介绍会比较好,第一部分是用const和enum替换不带参的宏,第二部分是用inline替换带参的宏. 第一部分:用const和enum替换不带参宏 宏定义#define发生在预编 ...
- NO.2: 尽量以const,enum,inline 替换 #define
1.首先#define 定义不重视作用域(scope),虽然可以#undef控制,但是不美观,还存在多次替换的问题,以及没有任何封装性. 2.const XXX_XX,保证其常量性以及可控的作用域,如 ...
- Effective C++阅读笔记_条款2:尽量以const,enum,inline替换#define
1.#define缺点1 #define NUM 1.2 记号NUM可能没有进入记号表,在调试或者错误信息中,无法知道1.2的含义. 改善:通过const int NUM = 1.2; 2.#dein ...
- 条款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]; ...}; 万一你的编译器(错误地)不允许 ...
- 条款2:尽量以const, enum, inline替换#define
原因: 1. 追踪困难,由于在编译期已经替换,在记号表中没有. 2. 由于编译期多处替换,可能导致目标代码体积稍大. 3. define没有作用域,如在类中定义一个常量不行. 做法: 可以用const ...
- 尽量用const,enum,inline代替define
在读<Effective C++>之前,我确实不知道const,enum,inline会和define扯上什么关系,看完感觉收获很大,记录之. define: 宏定义. 在编译预处理时,对 ...
- 条款2:尽量使用const ,enum,inline替换define
宁可使用编译器而不用预处理器 假设我们使用预处理器: #define ABC 1.56 这标识符ABC也许编译器没看到,也许它在编译器处理源码前就被预处理器移走了,于是“标识符”ABC没有进入标识符列 ...
- Effective C++之条款2:尽量以const enum inline替换 #define
本文的标题也可以改成“用编译器替换预处理器”: const double AspectRatio = 1.653; //最好使用上述代码替换下述代码: #define ASPECT_RATIO 1.6 ...
随机推荐
- 创业6&7
周末两天泡咖啡店. 起不来,只好下午去. 周六5点到9点. 周日3点到12点. 1)整理直播课程讲义.完成50%. 2)修改GMTC演讲稿.完成. 招行的单子还是拒了,目前还没准备好高可用的App服务 ...
- Linux网络编程系列-TCP编程实例
实例: client #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #inc ...
- EF架构~linq模拟left join的两种写法,性能差之千里!
回到目录 对于SQL左外连接我想没什么可说的,left join将左表数据都获出来,右表数据如果在左表中不存在,结果为NULL,而对于LINQ来说,要实现left join的效果,也是可以的,在进行j ...
- 简单总结java 语法
通过学习慢慢的爱上了这门语言,在Java的学习过程中,可能会遇到形形色色的问题不容易解决,应多去专业论坛了解相关的知识,书本上的知识有限.要会从网上搜索有用的信息加以整理,促进学习的深入和知识水平的提 ...
- 每天一个linux命令(9):touch 命令
linux的touch命令不常用,一般在使用make的时候可能会用到,用来修改文件时间戳,或者新建一个不存在的文件. 1.命令格式: touch [选项]... 文件... 2.命令参数: -a ...
- 高性能Cordova App开发学习笔记
高性能Cordova App开发学习笔记 文件结构 添加插件 构建准备 各个www的作用,prepare命令会将hello\www的内容会拷贝到platform下的wwww目录,知道该改哪里了吧?如果 ...
- Python为什么不隐式实现self
Python为什么不隐式实现self Python中类的方法都需要显式的传入一个self占位参数,这让写过C#,Java,PHP,Javascript的我很是不习惯,但是Python这么吊,肯定是有他 ...
- java webservice 总结(学会读别人的webservice并且通过代理模式访问)
公司做的系统之间的交互用到了webservice做交互,现在对webservice做一个总结. 1.配置已有的webservice webservice主要包括 xml/json:作为传输数据的格式 ...
- WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要针对WPF项目 ...
- Oracle Dataguard之物理standby的基本配置
尽管网上有很多Oracle Dataguard的配置教程,但不难发现,很多采用的是rman duplicate这种方法,尽管此种方法较为简便.但在某种程度上,却也误导了初学者,虽说也能配置成功,但只知 ...