effective C++读书笔记

news2024/11/19 16:31:56

目录

用const,enum,inline去替换#define

尽可能去使用const

 确保对象使用前已被初始化


这是effective C++中的第一大章节:让自己习惯c++

用const,enum,inline去替换#define

当用使用这样的代码:

#define ASPECT RATIO 1.653

记号名称ASPECT RATIO可能未被编译器看见;也许在编译器开始处理源码之前它就被预处理器移走了。于是记号名称ASPECT RATIO有可能没进入记号表(symbol table)内。若使用了这个常量但获得一个编译错误信息时,你将很难追踪错误所在。这个错误信息也许会提到1.653而不是ASPECT RATIO。

1.ASPECT RATIO被定义在一个非你所写的头文件内,你肯定对1.653以及它来自何
处毫无概念

2.你所使用的名称可能并未进入记号表,在记号式调试器也造成很大困扰。

最好使用一个常量来替代上面的宏。

const double Puioa=1.653

这里在补充两点:

1.定义常量指针

常量定义式通常被放在头文件内(以便被不同的源码含
入),因此有必要将指针(而不只是指针所指之物)声明为const.例如若要在头
文件内定义一个常量的(不变的)char*-based字符串,你必须写const两次:
const char*const authorName ="Scott Meyers";

2.class内的专属常量

为了将常量的作用域(scope)限制于class内,你必须让它成为class的一个成员(member);而为确保此常量至多只有一份实体,你必须让它成为-一个static成员。

例如:

class GamePlayer
private:
static const int NumTurns =5;//常量声明式
int scores [NumTurns];       //使用该常量
};

上面的只是声明,不是定义,只要不取它的地址,可以直接声明不定义的去使用它。但若要取地址或者编译器要看到它的定义式的话,就要在外面去定义它。

const int GamePlayer::NuTurns;
//上面声明时以获得初值,定义时可不设初值

补充:

1.class的专属常量不能用#define去弄,宏在编译后,后面都有效,除非(#undef)。

2.若编译器不支类内static const 成员在声明时获得初值,可在类外定义时附上初值。

3.若编译器错误的不允许static整型class常量完成类内初值设定,可用“the enum hack"补偿做法。

例如:

class GamePlayer
{
private:
	//static const int NumTurns=5;//常量声明式,若这边语句编译器出错
	int scores[NumTurns];       //使用该常量
};

解决办法:

class GamePlayer
{
private:
	//static const int NumTurns=5;//常量声明式
	enum count
	{
		NumTurns = 5
	};
	int scores[NumTurns];       //使用该常量
};

理由:枚举与#define更像,例如取const 修饰的变量地址是合法的,但取一个enum地址是不允许,取一个#define的地址也不允许。若不想别人用一个指针或者引用去关联它,enum可以做到。enum和#define一样,绝对不会导致非必要的内存分配。

 当使用类似于函数的宏时,例如:

发现第一次A99变到了101,第二次从101变到了102,即使为所有参数加上括号也是一样的。

用template inline 函数

template<typename T>
inline void call(const T& a, const T& b)
{
	f(a > b ? a : b);

}

这里不需要在函数本体中为参数加上括号,也不需要操心参数被核算(求值)多次……等等。此外由于call是个真正的函数,它遵守作用域(scope)和访问规则。

尽可能去使用const

const修饰指针:

const出现在*左侧,说明被指物是常量,const出现在*右侧,说明指针是常量。若出现在两侧,表明两        者都是常量。

const成员函数:

将成员函数用const去修饰,是为了确认该成员函数可作用于const对象上。1.可以使class接口更容易理解,可以知道哪个函数可以改变对象内容而哪个函数不可以。2.使操作 const对象 成为可能。

看一段代码:

 cosnt对象调用的是const版本。注意,若operator[] 返回的是char,不是char&,那么tb[0]='a',这样就无法编译通过,因为返回的是一个内置类型,改变它就不合法。即使可以改变,你也没有改变text的内容。

const的两个流派概念:bitwise constness(physical constness)与logical constness。

bitwise const认为成员函数只有在不更改对象之任何成员变量( static除外)时才可以说是const。不幸的是许多成员函数虽然不具备const性质却能通过bitwise测试。

例如:

 再看如下的操作:

 其中不含错误,可以编译通过,但创建一个常量对象并设以某值,而且只对它调用const成员函数,终究还是改变了它的值。这种情况就有了logical constness阵营,一个const成员函数可以修改它所处理的对象内的某些bits,但只有在客户端侦测不出的情况下才得如此。

再看下面一个例子:

 这个length函数内的this指针是被const修饰的,但他的成员在这函数内是要被修改,这种情况肯定不属于bitwise constness,但现在却无法编译通过。

解决办法:利用mutable释放掉non-static成员变量的bitwise constness约束。

例如:

在const与non-const成员中避免重复

上面的代码用mutable去解决问题,但它不能解决所有问题。假设TextBlock(和CTextBlock)内的operator[]不单只是返回一个reference指向某字符,还要执行其它功能。把所有这些同时放进const和non-const operator[]中,可能会成为一个长度很长的隐喻式inline函数。

例如:

 里面可能包含大量的代码重复,以及伴随的编译时间、维护、代码膨胀等问题。应该实operator[]的机能-一次并使用它两次。也就是说,你必须令其中一个调用另一个。这促使我们将常量性转除(casting away constness)。合理的做法是用non-constness函数调用const成员函数,其中需要转型动作。

例如:

  对第二个operator[]解释:

首先是要明白是用non-constness函数调用constness函数,首先这要把this指针用const去修饰,那么它就会去调用constness版本函数,当constness函数的返回值又是const char&,所以再把返回值得数据类型改为char&。

 确保对象使用前已被初始化

这里关于类成员通过构造函数赋值,在初始化列表进行初始化不再细谈。只简单介绍几点:

C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前,发生于这些成员的default构造函数被自动调用之前。但对于内置类型不保证。

最好在初值列表中列出所有成员变量,以免遗漏。

成员变量是const或者reference,不能被赋值,只能通过初始化列表。

当class有许多构造函数,每个构造函数有自己的成员初值列。可能会导致许多重复的代码操作,这种情况下可以合理地在初值列中遗漏那些“赋值表现像初始化一样好”的成员变量,改用它们的赋值操作,并将那些赋值操作移往某个函数(通常是private),供所有构造函数调用。

class的成员变量是按声明顺序初始化。

但要重点关注non-local static对象”的初始化次序。

看下面一段代码:

 除非tfs在tempDir之前先被初始化,否则tempDir的构造函数会用到尚未初始化的tfs。,C++对“定义于不同的编译单元内的non-local static对象”的初始化相对次序并无明确定义。

解决办法:

 C++保证,函数内的local static对象会在“该函数被调用期间”“首次遇上该对象之定义式”时被初始化。如果你以“函数调用”(返回一个reference指向local static对象)替换“直接访问non-local static对象”,你就能保证你所获得的那个reference将指向一个历经初始化的对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/124801.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图像风格迁移---基于多适应网络的任意风格传输

ABSTRACT 任意风格转换是一个具有研究价值和应用前景的重要课题。给定一个内容图像和引用的风格绘画&#xff0c;一个所需的风格转换将使用风格绘画的色彩色调和生动的笔画模式渲染内容图像&#xff0c;同时保持详细的内容结构信息。风格迁移方法首先学习内容和内容和风格引用…

推荐系统的矩阵分解

0 序言 推荐系统中基于内容的协调过滤算法通过用户之间的相似性或者物品之间的相似性&#xff0c;通过相似性来为用户做决策和推荐&#xff1b;基于内容的协调过滤算法在实际生产环境中&#xff0c;User或Item的数据量非常大&#xff08;百万级别&#xff09;&#xff0c;存储…

操作系统期末考试必会题库3——处理机调度

1、假设一个系统中有5个进程&#xff0c;它们处于就绪状态的时刻和估计运行时间如下表所示&#xff0c;忽略I/O以及其它开销时间&#xff0c;若分别按先来先服务&#xff0c;最短进程优先&#xff0c;最短剩余时间优先、响应比优先、时间片轮转&#xff08;时间片&#xff1d;1…

世界杯 | 其实世界杯结束之前,卡塔尔就开拆体育场了...

大家好&#xff0c;这里又是建模助手。 世界杯已经圆满落幕&#xff0c;梅老板满载而归&#xff0c;但阿根廷与法国的这场世界杯决赛注定载入史册&#xff0c;成为永恒经典&#xff0c;或许将会是世界杯历史上最精彩的决赛之一。 &#xff08;梅老板捧起大力神杯那一刻&#x…

人工鱼群算法参数寻优及可视化(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 人工鱼群优化算法是一种基于模拟鱼群行为的优化算法&#xff0c;是由李晓磊等在2002年提出的一种新型的寻优算法。人工鱼群主要…

黑马Hive+Spark离线数仓工业项目--数仓事实层DWB层构建(1)

整体目标&#xff1a;构建数仓中的DWB&#xff1a;主题事务事实表 核心的主题事实的构建&#xff1a;SQL实现 主题的指标 原始事务事实数据【DWD】&#xff1a;订单数据 主题事务事实数据【DWB】&#xff1a;订单主题 - 主题周期快照事实表&#xff1a;数据应用层【ST&#…

一场4800亿“锂电”战事,瑞浦兰钧射出三支“价值之箭”

顺势而为&#xff0c;是一家企业成功突围的最佳利器。 如今&#xff0c;几乎所有企业都被“碳达峰碳中和”的国家级战略所影响。在此大势的推动之下&#xff0c;锂离子电池、清洁能源等产业也随之进入高速发展期。工信部数据显示&#xff0c;上半年全国锂离子电池产量超过280G…

HNU编译原理实验二cminus_compiler-2022-fall

前言&#xff1a;个人感觉比第一次的难&#xff0c;借鉴了前辈的报告才勉强看懂在干嘛 lab2实验报告实验要求 本次实验需要先将自己的 lab1 的词法部分复制到 /src/parser 目录的 lexical_analyzer.l并合理修改相应部分&#xff0c;然后根据 cminus-f 的语法补全 syntax_analy…

3.3 直接耦合放大电路

工业控制中的很多物理量均为模拟量&#xff0c;如温度、流量、压力、液面、长度等&#xff0c;它们通过各种不同传感器转化成电量后也均为缓慢变化的非周期性信号&#xff0c;而且比较微弱&#xff0c;因而这类信号一般均需通过直接耦合放大电路后才能驱动负载。 一、直接耦合…

二叉树,红黑树,B树、B+树的区别

树的概念 树的演变 二叉搜索树 二叉搜索树可以提高查询效率&#xff0c;左小右大&#xff0c;但是他不好掌握根节点的数字是哪个&#xff0c;容易一边倒&#xff0c;导致层数变多&#xff0c;降低效率 平衡二叉搜索树 平衡二叉搜索树在二叉搜索树的基础上,通过控制任意一个节…

Shell“语言程序设计基础......“

Shell语言也有设计基础吗?...... 没有所谓的语言程序设计基础往往是一种就是菜鸡互啄的一种状态......哦,据说当年,发明笔记本电脑的人(想出发明笔记本电脑这个创意的人)一开始的工作是写说明书的Linux 或者 Unix 发明的那个年代应该还没有这种充满了营销的或者应试的表述方法…

密码学 密钥管理

密钥管理 出发点&#xff1a;在一种安全策略指导下的密钥产生&#xff0c;存储&#xff0c;分配&#xff0c;删除&#xff0c;归档和应用方案。 目的&#xff1a;维持系统各实体之间的密钥关系&#xff0c;抗击各种威胁&#xff1a; 1.密钥泄露 2.密钥和公钥身份真实性丧失 3…

计算机内存机制精讲

全文目录1、一个程序在计算机中到底是如何运行的&#xff1f;2、虚拟内存到底是什么&#xff1f;虚拟地址中间层思想3、虚拟地址空间以及编译模式CPU的数据处理能力编译模式32位编译模式64位编译模式4、内存对齐&#xff0c;提高寻址效率5、内存分页机制&#xff0c;完成虚拟地…

react-native学习过程记录

1、关于react-native init 创建项目报错 cli.init is not a function 问题解决 直接采用npx react-native init chapter2 --version 0.68.2 创建项目&#xff08;即指定version&#xff09; 参考地址&#xff1a;https://blog.csdn.net/qq_42231156/article/details/126396576…

【云原生进阶之容器】第二章Controller Manager原理剖析--2.1节Controller Manager综述

1 K8S Controller Manager原理解析 1.1 Controller Manager作用简述 一般来说,智能系统和自动系统通常会通过一个“操作系统”不断修正系统的工作状态。在Kubernetes集群中,每个Controller都是这样的一个"操作系统",它们通过APIServer 提供的(List-Watch)接口实…

小程序集成Three.js开发常见问题

1.加载模型后开发者工具卡顿 我想很多小伙伴都遇到过这个问题&#xff0c;网上很多方法&#xff0c;说什么清缓存&#xff0c;清内存&#xff0c;基本作用都不大。在不断的摸索中&#xff0c;我逐渐找到了一些解决的办法&#xff0c;希望对你有帮助。 (1) 截至发文时间&#…

Java-集合(1)

什么是集合&#xff1f; 在前面的学习中&#xff0c;保存多个数据&#xff0c;用的是数组。 但是数组有很多不同的地方&#xff1a; 1.长度开始时必须指定&#xff0c;且一旦指定无法更改 2.保存的必须为同一类型元素&#xff0c;虽说可以多态保存&#xff0c;但是限制性也很大…

再学C语言17:类型转换

语句和表达式通常只应该使用一种类型的常量和变量 如果使用混合类型&#xff0c;C将会使用一个规则集合自动完成类型转换 一、基本的规则 1&#xff09;当出现在表达式中时&#xff0c;有符号和无符号的char类型和short类型都将自动被转换为int&#xff08;在需要的情况下将…

新华三“智・行中国2022”|大厂行动,如何擘画“内循环”的数字未来?

作者 | 曾响铃 文 | 响铃说 继农业经济、工业经济之后&#xff0c;数字经济登上历史的舞台&#xff0c;成为大国的主要经济形态。在我国&#xff0c;根据中国信息通信研究院发布的《中国数字经济发展白皮书&#xff08;2022年&#xff09;》&#xff0c;截至2021年&#xff0…

关于浙大MPA复试的一些常规问题

2022年联考笔试刚刚落下帷幕&#xff0c;就收到很多小伙伴关于浙大MPA项目复试的问题咨询&#xff0c;趁着今天有空就大家问的一些问题在这里统一做个回复哦~1、问&#xff1a;正常情况下多少分可以进入浙大MPA项目复试&#xff1f; 答&#xff1a;统计了2018——2022浙大MPA项…