我在阅读 《Effective C++ (第三版本)》 书时做了不少笔记,从中收获了非常多,也明白为什么会书中前言的第一句话会说:
对于书中的「条款」这一词,我更喜欢以「细节」替换,毕竟年轻的我们在打 LOL 或 王者的时,总会说注意细节!细节!细节~ —— 细节也算伴随我们的青春的字眼
针对书中的前两个章节,我筛选了 10 个 细节(条款)作为了本文的内容,这些细节也相对基础且重要。
针对这 10 细节我都用较简洁的例子来加以阐述,同时也把本文所提及细节中的「小结」总结绘画成了一副思维导图,便于大家的阅读。
后续有时间也会继续分享后面章节的笔记,喜欢的小伙伴「点击左上角」关注我~
温馨提示:本文较长,建议收藏阅读。
正文 1 让自己习惯C++ 细节 01:尽量以const,enum,inline 替换 #define#define 定义的常量有什么不妥?
首先我们要清楚程序的编译重要的三个阶段:预处理阶段,编译阶段和链接阶段。
#define
是不被视为语言的一部分,它在程序编译阶段中的预处理阶段的作用,就是做简单的替换。
如下面的 PI
宏定义,在程序编译时,编译器在预处理阶段时,会先将源码中所有 PI
宏定义替换成 3.14
:
#define PI 3.14
程序编译在预处理阶段后,才进行真正的编译阶段。在有的编译器,运用了此 PI
常量,如果遇到了编译错误,那么这个错误信息也许会提到 3.14 而不是 PI,这就会让人困惑哪里来的3.14
,特别是在项目大的情况下。
解决之道:以 const 定义一个常量替换上述的宏(#define)
作为一个语言变量,下面的 const 定义的常量 Pi
肯定会被编译器看到,出错的时候可以很清楚知道,是这个变量导致的问题:
const doule Pi = 3.14;
如果是定义常量字符串,则必须要 const
两次,目的是为了防止指针所指内容和指针自身不能被改变:
const char* const myName = "小林coding";
如果是定义常量 string
,则只需要在最前面加一次 const
,形式如下:
const std::string myName("小林coding");
#define 不重视作用域,所以对于 calss 的专属常量,应避免使用宏定义。
还有另外一点宏无法涉及的,就是我们无法利用 #define
创建一个 class
专属常量,因为 #define
并不重视作用域。
对于类里要定义专属常量时,我们依然使用 static
+ const
,形式如下:
class Student {
private:
static const int num = 10;
int scores[num];
};
const int Student::num; // static 成员变量,需要进行声明
如果不想外部获取到 class 专属常量的内存地址,可以使用 enum 的方式定义常量
enum
会帮你约束这个条件,因为取一个 enum
的地址是不合法的,形式如下:
class Student {
private:
enum { num = 10 };
int scores[num];
};
#define 实现的函数容易出错,并且长相丑陋不易阅读。
另外一个常见的 #define
误用情况是以它实现宏函数,它不会招致函数调用带来的开销,但是用 #define
编写宏函数容易出错,如下用宏定义写的求最大值的函数:
#define MAX(a, b) ( { (a) > (b) ? (a) : (b); } ) // 求最大值
这般长相的宏有着太的缺点,比如在下面调用例子:
int a = 6, b = 5;
int max = MAX(a++, b);
std::cout
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?