effective C++ 读后感(三) 尽可能使用const

手把手写C++服务器(39):《Effective C++》读后感和一些思考 《Effiective C++》是我最喜欢的书籍之一(或许没有之一),里面详细介绍了改善程序设计的55种具体做法,对于C++程序员来说是一笔宝贵的财富,同时也是面试的高频考点,值得每隔一段时间就拿出来复习!! 阅读详情

三、尽可能使用const

再细心的程序员也会有犯错的时候。通过语言自身的机制来对程序产生约束,可以大大减少错误的发生。而如何利用这些机制就要看程序员的习惯了。

事实上,这些机制其实就是让编译器能更加准确地理解程序员的用意, 这样当程序运行方式与程序员的真实用意不相符时,就可以提醒程序员“这个地方会不按要求执行,请修改一下”。

const就是一个很好的例子。它让编译器知道程序员定义的变量是不允许被更改的,编译器会强制实施这个约束。

我在前一篇文章里对const作了一些介绍。const在STL中也有用到,比如说迭代器,如果不想让迭代器指向不同的东本,可以定义它为const_iterator。

const还可以与函数返回值,参数和成员函数自身产生关联。

const与返回值关联和参数

将函数参与设定为const比较好理解,就是不希望在函数内部出现更改参数的行为。但为什么有时候还要将返回值也设定为const呢?我们来看下面的例子:

#include <iostream>
using namespace std;
class Complex {
public:
	double real, imag;
	Complex(double r, double i): real(r), imag(i){}
	Complex operator+(const Complex &);
	bool operator==(const Complex &) const;
	operator void*();
};
Complex Complex::operator +(const Complex &c) {
	return Complex(this->real + c.real, this->imag + c.imag);
}
bool Complex::operator==(const Complex &c) const {
	return this->real == c.real && this->imag == c.imag;
}
Complex::operator void *() {
	return this;
}

int main() {
	Complex a(1, 2), b(2, 3), c(3, 4);
	if(a + b = c)
		cout << "a plus b equals to c" << endl;
	else
		cout << "a plus b does not equal to c" << endl;
}

在main函数中,本来是要判断虚数a + b与c是否相等,但由于少写了一个等号,所以程序运行结果成了:

a plus b equals to c

这显然是不对的。

这时我们就可以看出将返回值设为const的用处了,如果将+运算定义为:

const Complex operator+(const Complex &);
那么当要将c赋值给a+b的结果时,编译器会报错,这样我们就能很快发现问题了。

事实上,C++的内置类型就是这么做的,比如说如果a,b,c都是int型,a+b=c也会编译报错。将返回值设为const可以预防“没意思的赋值动作“


const 成员函数

类似于Java的final,C++中const对象只能调用const成员函数。上例中的==重载就是const成员函数。在const成员函数中不允许修改对象的属性。

当我们用STL的priority_queue时,需要重载<运算符,而且必须声明为const 成员函数。这是因为,priority_queue的定义为:

template <class T, class Container = vector<T>,
  class Compare = less<typename Container::value_type> > class priority_queue;

其中用到了默认为less的比较类来比较大小。less定义如下:

template <class T> struct less {
  bool operator() (const T& x, const T& y) const {return x<y;}
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};
这是一个函数对象,其成员函数是const的,所以不允许x和y的值被改动。这就要求<运算也是const的。这也是一个很好的习惯。我们不希望在比较两个对象的过程改变对象的值。

两个成员函数如果只是常量性不同,可以被重载。

#include <iostream>
using namespace std;

class A {
public:
	void print() {
		cout << "this is print" << endl;
	}
	void print() const {
		cout << "this is const print" << endl;
	}
};
void test1(A a) {
	a.print();
}
void test2(const A a) {
	a.print();
}
int main() {
	A a;
	test1(a);
	test2(a);
	return 0;
}

输出结果为:

this is print
this is const print
当对象为const时,由于常量要求只能调用const成员函数,所以test2调用的是第二个print函数。而a不是常量,test1将调用第一个print().

C++如何保证常量性

C++使用的是bitwise constness(又称physical constness)来保证常量性的。也就是说const成员函数不能修改对象的任何一个bit,即不存在对成员属性的赋值操作(static成员变量除外)。

这样看似非常保险了,但其实bitwise constness有些时候达不到我们对const的要求。比如下面的例子:

#include <iostream>
using namespace std;

class MyString {
	char *s;
public:
	MyString(string a) {
		int len = a.length();
		s = new char[len + 1];
		for(int i=0; i<len; i++)
			s[i] = a[i];
		s[len] = '\0';
	}
	char &operator[](int position) const {
		return s[position];
	}
	void print() const {
		cout << s << endl;
	}
};

int main() {
	const MyString test("hello");
	test[0] = 'H';
	test.print();
	return 0;
}

因为test对象里只有一个指针,而[]运算符里也没有更改这个指针,所以符合bitwise constness。但结果是反直观的,因为我们将test声明为const是想让test内容不被改变。

这就引出了logical constness。这指的是一个const成员函数可以修改对象内的某些bits,但只有在客户端侦测不到的情况下才能如此(比如类似缓存结果),以下是书中的一个例子:

#include <iostream>
#include <cstring>
using namespace std;
class CTextBlock {
	char *pText;
	mutable size_t textLength;
	mutable bool lengthIsValid;
public:
	size_t length() const;
};
size_t CTextBlock::length() const {
	if(!lengthIsValid) {
		lengthIsValid = true;
		textLength = strlen(pText);
	}
	return textLength;
}

mutable关键字可以解决bitwise constness的约束。上例实现了一个logical constness。

有时候可能希望一个const对象临时调用一个非const的方法,这时可以利用const_cast将const对象转成非const的,然后再利用static_cast将其转回到const。

基于Java17、SpringBoot、vue3、antdv-next、uniapp等主流技术构建的全场景极速开发平台 MDP内置3个web端、1个移动端 重点解决用户中心、开发者平台、管理后台3个应 MDP-主数据平台,后端项目。专注于单点登录解决方案。内置用户中心、开发者平台、管理后台3个应用。包含:单点登录、Oauth2 登录、用户身份管理、应用申请、应用接入、主数据维护、主数据订阅、主数据广播、应用接口调用、接口管理管理和查看、系统配置等功能。 立即下载

相关推荐

Win7时间修复(时间错误修复文件)

运行方法:解压后运行reg文件即可。 支持的Win7版本: 1. Windows 7 Starter(入门版 / 初级版) 2. Windows 7 Home Basic(家庭普通版) 3. Windows 7 Home Premium(家庭高级版) 4. Windows 7 Professional(专业版) 5. Windows 7 Enterprise(企业版) 6. Windows 7 Ultimate(旗舰版) 7. Windows 7 Professional for Embedded Systems(嵌入式专业版) 8. Windows 7 Ultimate for Embedded Systems(嵌入式旗舰版)

effective C++ 读后感(二) 尽量以const, enum, inline替换 #define

二、尽量以const, enum, inline替换 #define #define在C语言中是常见的,用于定义常量。如: #define PI 3.14 但PI会在编译之前就被预处理了,代码中的PI会被3.14替代。所以PI并没有进入记号表内。因此如果代码出现问题的话,错误信息里可能会提到3.14,而没有PI,这会增大查找问题的难度。而且这也会给调试带来一些麻烦。 比如说下面的例子:

warrenfws的专栏 401

YOLO26算法行人行走检测+训练好的模型+102张数据集+pyqt可视化界面.zip

附训练好的 YOLO 权重与 PyQt 可视化检测界面,页面底部含可视化效果预览,毕设/课设开箱即用。 【数据集概况】 · 检测类别(中文):[行走的人(person walking)] 【训练曲线与评估图】 【模型训练配置】 参数 | 值 模型 | yolo26n 训练轮数 | 100 epochs 输入尺寸 | 640x640 批次大小 | 24 优化器 | auto 初始学习率 | 0.01 训练设备 【关键指标汇总】 训练了 67 个 epoch,最终轮指标: 指标 | 数值 mAP50 | **0.8000** mAP50-95 | 0.5620 Precision | 0.5795 Recall | 0.8235 train/box_loss | 0.9538 train/cls_loss | 1.9897 val/box_loss | 0.9034 val/cls_loss | 2.7344 【训练过程分析】 进入训练阶段后,模型一开始的 mAP50 和 mAP50-95 均为 0.8000 和 0.5620,表明在开始阶段模型的收敛情况良好。从第 30 轮起,训练集的 mAP50 值稳定在了 0.8000,这说明模型在这之前能够迅速捕捉到主要目标,但精度提升的余地已然不大。同时,mAP50-95 在训练集上表现略差,从第 50 轮开始慢慢往上走至 0.5620。这反映出模型在检测更小、更远的目标上还存在一定差距,精度成为瓶颈。 随着训练深入,模型在验证集上的表现开始分化。从第 60 轮开始,验证集的 mAP50 和 mAP50-95 值分别为 0.7500 和 0.4500,相比训练集下降明显,表明模型存在一定程度的过拟合现象。训练集上的 box loss 和 cls loss 值分别为 ... 使用场景:毕业设计、课程设计、深度学习入门、工业场景落地验证。

关于 effective C++读后的认识

 首先我想说的是《effective C++》是一本有雄厚经验的高级程序员的个人总结,每一个条款都是作者的数十年工作经验的精华。 是一本真正长见识的书。从书的结构设计来看。作者一步一步的把我们引向c++面向对像的世界里,教会 我们如何设计出健壮、易用、高效率的c++类。第一章用c与c++比较,告诉我们c++比c的好处。还强 烈建议我们用C++里的const,inline等。

Fchentianbao的专栏 850

科技中介服务机构想要提升服务效率,需要哪些数智工具支持?.docx

科技中介服务机构想要提升服务效率,需要哪些数智工具支持?

usb 扩容盘检测修复工具源码,编译产物

usb 扩容盘检测修复工具源码,编译产物

Effective C++读书笔记---让自己习惯C++

* 声明式是告诉编译器某个东西的名称和类型。 * 签名式是指参数和返回值。一个函数的签名等同于该函数的类型(C++对签名式的官方认定不包括返回值) * 将函数声明为 explicit ,可以阻止他们被用来执行隐式转换,但他们仍可以用来进行下你是类型转换 * 其他静态成员只能在类里边进行声明,类外进行初始化。格式为: 类域::类型 变量名 = 初始值 * 类的静态常量成员可以在类里边进行初始...

半暖的博客 575

政府科技管理者在推动科技成果转化时,如何解决政策对接不精准导致的项目落地难?.docx

政府科技管理者在推动科技成果转化时,如何解决政策对接不精准导致的项目落地难?

effective C++ 读后感(五) 了解C++默默编写并调用哪些函数

五、了解C++默默编写并调用哪些函数

warrenfws的专栏 593

融合UWB和IMU割草机定位EKF研究(Matlab代码实现)

内容概要:本文主要介绍了一个名为“Plecs全桥LLC谐振变换器仿真模型”的技术资源,该资源聚焦于电力电子领域中的LLC谐振变换器建模与仿真,涵盖开环、闭环控制、软启动设计及参数优化等核心内容。文档不仅提供了LLC变换器的详细建模方法与仿真案例,还系统梳理了其在高效电源转换系统中的应用,包括隔离型全桥拓扑结构的设计与性能分析。此外,资源汇总了大量Matlab/Simulink仿真模型及相关科研方向,涉及新能源并网、储能控制、电机驱动等多个前沿领域,全面展示LLC谐振变换器在现代电力系统中的关键技术实现路径。同时,文档附带多种学习资料获取途径,如网盘链接和公众号资源,便于研究人员深入实践与拓展研究。; 适合人群:具备扎实的电力电子、自动控制理论基础,从事新能源发电、开关电源设计、电力系统仿真等相关领域的研究生、工程师及科研人员。; 使用场景及目标:①深入理解LLC谐振变换器的工作原理、建模方法与控制策略;②开展电力电子变换器的仿真验证与参数优化设计;③支撑科研项目、学位论文或工程项目的系统仿真与方案验证; 阅读建议:建议结合所提供的仿真模型与参考文献,使用Plecs或Simulink软件进行动手实践,重点掌握LLC谐振变换器的建模流程、闭环控制设计、软启动机制及参数调试技巧,以全面提升在实际工程中的应用与创新能力。

基于变频控制的多相交错LLC谐振变换器闭环仿真(Simulink仿真实现)

基于变频控制的多相交错LLC谐振变换器闭环仿真(Simulink仿真实现)内容概要:本文主要介绍了基于Plecs的全桥LLC谐振变换器仿真模型,涵盖变频控制下的多相交错LLC谐振变换器闭环仿真、V2G电动汽车ACDC整流与双向CLLC谐振变换器充放电仿真、LLC谐振变换器的开环与闭环软启动设计,以及储能系统中双向Buck-Boost变换器结合模型预测电流控制和电压下垂控制的仿真研究。同时,文档列举了多种电力电子系统与控制策略的Simulink/Plecs仿真案例,涉及三相交错并联Buck变换器、三电平Buck直流变换器、单相Boost PFC电路等,展示了丰富的电力变换器建模与控制技术。此外,还包括参数设计报告、计算书及相关参考文献,适用于从事电力电子、新能源发电、电动汽车充放电系统等领域的研究人员和技术开发人员。; 适合人群:具备电力电子、自动控制理论基础,从事新能源、电动汽车、电力系统等相关领域研究的研发人员、高校研究生及高年级本科生。; 使用场景及目标:① 学习和掌握LLC谐振变换器及其他典型电力电子变换器的工作原理与建模方法;② 实现闭环控制策略如变频控制、软启动、模型预测控制、下垂控制等的仿真验证;③ 支持科研项目、毕业设计或工程开发中的系统仿真与优化设计。; 阅读建议:建议结合文中提供的仿真模型、设计报告与参考文献,逐步搭建并调试相应系统,重点关注控制策略的实现细节与参数整定过程,以深入理解系统动态响应特性与控制性能。

《effective C++ 改善程序与设计的55个具体做法》读书笔记第一弹

说明:部分涉及C++较高级功能的条款,如智能指针、并行编程等暂不研读,后续用到这部分再说,涉及这部分的条款仅标注并跳过不研究 1. 条款01 2. 条款02–尽量以const、enum、inline替换 #define 对于单纯常量,最好以const对象或者enums替换#define; 对于形似函数的宏,最好改用inline函数替换#define; 3. 条款03–尽可能使用const const对指针变量 char p1[]="Hello"; char* p2=p1; const char* p

Nancy_fairy的博客 234

独立储能的现货电能量与调频辅助服务市场出清协调机制(Matlab代码实现)

内容概要:本文标题为“Plecs全桥LLC谐振变换器仿真模型”,但实际内容严重偏离主题,文档中混杂了大量来自优快云博客平台的无关信息,涵盖多个不同领域的Matlab/Simulink仿真项目,如电力系统优化、无人机路径规划、机器学习预测、微电网调度、卡尔曼滤波、无线能量传输等,导致核心内容缺失。文档未能提供关于Plecs平台下全桥LLC谐振变换器的建模方法、电路结构、参数设计、控制策略或仿真结果等关键技术细节,实质信息与标题完全不符,不具备作为该主题参考资料的有效性。; 适合人群:从事电力电子变换器研究、电源系统设计及相关领域的工程师、高校研究生与科研人员,尤其是希望掌握LLC谐振变换器建模与仿真的专业技术人员。; 使用场景及目标:① 学习并掌握全桥LLC谐振变换器的工作原理与Plecs仿真建模技术;② 开展高效电源转换器的研发与性能优化;③ 作为教学或科研项目中电力电子电路仿真的参考资料。; 阅读建议:鉴于文档内容与标题严重不符,建议读者谨慎甄别,优先选择专业书籍、学术论文或官方仿真软件教程等权威资源进行学习,避免被无效信息误导。

Effective C中文版改善C程序的50种方法 读后小感

为你的常量选择readonly而不是const:Const:编译时常量,运行快,可能产生错误(对性能要求苛刻,且随程序运行时间过去,值不会发生改变)。编译时常量仅限于数字和字符串。ReadOnly:运行时常量,可以是任何类型的数据,在运行时才确定值。 选择is或者as操作符而不是做强制类型转换:强制转换的方法为了检测转换是否把一个null的对象进行强制转换,而不得不添加一个捕获异常的结构。nul...

weixin_34233421的博客 170

基于多元宇宙优化算法的微电网日前经济调度模型研究(Matlab代码实现)

内容概要:文档《Plecs全桥LLC谐振变换器仿真模型.txt》虽以“Plecs全桥LLC谐振变换器仿真模型”为名,实则是一份涵盖电力电子、电力系统、电机控制、新能源并网、微电网优化调度、储能系统、电动汽车调度、无人机路径规划、信号处理、雷达与状态估计等多个技术方向的综合性仿真资源汇编。内容依托Matlab/Simulink、PLECS、PSCAD等主流仿真平台,聚焦于现代优化算法(如粒子群、遗传算法、多目标差分进化、多元宇宙算法等)在能源系统建模、参数优化与控制策略设计中的应用。文档不仅提供了丰富的仿真案例和研究主题,还附带大量可下载的仿真代码、模型及参考文献,构成一个服务于科研与教学的资源集合。; 适合人群:具备电力电子、电力系统、自动化、控制工程或相关专业背景的研究生、科研人员及工程技术人员,尤其适合熟悉Matlab/Simulink、PLECS或PSCAD等仿真工具并从事相关领域研究的人员。; 使用场景及目标:①为电力系统动态分析、微电网能量管理、电机驱动控制、无人机路径规划等课题提供仿真建模思路与实例参考;②学习和复现先进智能优化算法在复杂工程问题(如经济调度、参数辨识、故障诊断)中的实现方法;③获取可用于学术论文撰写、毕业设计或科研项目申报的完整仿真资源与技术支持。; 阅读建议:此文档为典型的资源聚合型文本,建议读者根据自身研究方向有针对性地选择相关章节进行深入研读,优先关注与自己课题契合度高的仿真模型和算法实现,并结合所提供的代码与模型进行实践验证与二次开发,注意区分不同研究主题的边界,避免信息混淆。

隔离型全桥LLC谐振变化器建模及参数设计资料【仿真+设计报告+计算书】

内容概要:本文档系统性地介绍了隔离型全桥LLC谐振变换器的建模、参数设计与控制策略研究,配套提供Simulink闭环仿真模型、详细设计报告及Mathcad计算书等全套技术资料。内容涵盖变频与移相混合控制、谐振参数优化、软启动过程分析、恒压恒流双闭环控制等核心技术,并延伸至2.5kW双向全桥LLC、多相交错LLC等多种典型应用场景。此外,资料还整合了PFC、DAB、CLLC、三电平变换器等相关电力电子拓扑的仿真与控制设计资源,辅以PPT说明、参考文献与程序代码,构建了一个面向科研与工程实践的完整技术解决方案。; 适合人群:具备电力电子与电力系统基础知识,从事新能源变换器、高频开关电源、车载充电机、储能系统等方向研究的研究生、工程师及科研人员。; 使用场景及目标:① 掌握LLC谐振变换器的小信号建模方法与谐振腔参数匹配设计流程;② 学习高频软开关电路的闭环控制策略与稳定性分析方法;③ 借助仿真模型快速验证不同工况下的系统动态性能,支撑科研项目开发、论文撰写与产品原型设计。; 阅读建议:建议结合Mathcad计算书与Simulink仿真模型同步调试,重点剖析谐振元件选型依据、控制环路动态响应特性及闭环系统稳定性判据,强化理论与实践的深度融合,全面提升高频隔离变换器的工程设计能力。

上一篇: effective C++ 读后感(二) 尽量以const, enum, inline替换 #define
下一篇: effective C++ 读后感(四) 确定对象被使用之前已被初始化
warrenfws
博客等级 码龄17年 2粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值