96SEO 2026-02-19 10:24 0
上一期我们讲到类的6个默认构造函数中的拷贝构造函数这一期我们继续往下讲当然难点肯定是运算符重载了。

运算符重载是c为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数也具有其返回值类型函数名字以及参数列表其返回值类型与参数列表与普通的函数相似。
1.不能通过连接其他符号来创建新的操作符。
比如operator
4.作为类成员函数重载时其形参看起来比操作数数目少1因为成员函数的第一个参数为隐藏的this。
像上面的d1和d2两个参数该如何比较大小呢以前在C语言我们通常写一个函数是传两个日期的地址过去然后挨个用指针访问去比较最后返回布尔值这样会非常的麻烦而c的运算符重载正好解决了这个问题。
通过上面的代码和图片大家应该可以看到运算符重载对于自定义类型有多方便而运算符重载的规则我们也讲过那么写到类外什么样子呢
由于类外不可访问类内私有成员可以先将私有成员改为共用或者知道友元函数的用友元
我们可以发现运算符很多都是实现一两个其他的就可以复用了。
小于等于不就是大于的取反吗只需要知道类内函数有隐藏的参数this默认指向第一个操作数即可。
注意赋值运算符的重载并不是强制要求参数为这里要和拷贝构造区分赋值运算符即使用传值调用也可以使用不会发生无穷调用因为在传自定义类型参数的时候先拷贝构造一个临时变量然后将这个变量赋值给变量即可。
一般来说赋值给另一个对象是不需要返回值的但是为了实现连续赋值那么就必须返回被赋值的那个变量由于被赋值的对象不会被销毁所以为了不调用拷贝构造函数浪费空间直接使用引用返回即可。
如果有人写成d1
this是左操作数的地址d是右操作数的地址这样的好处就是即使赋值时出现操作数一样的情况也不会白白浪费空间。
注意运算符的顺序不是从右往左也不是从左往右这是要看操作符的结合性的。
我们之前说过类的6个默认函数即使我们不写编译器也会写一个默认的那么默认的能完成赋值重载的任务吗这个问题和拷贝赋值是一样的对于内置类型编译器可以完成赋值但是对于像栈那样需要开不同空间的必须我们手动去写一个赋值重载。
前面讲拷贝构造的时候忘记了一个细节那就是向上图中红色框起来的也是拷贝构造有些人会有疑问这里不是用赋值重载了吗其实并不是赋值重载的调用是针对两个已经实例化好的或定义的对象而像上图中d5还没有定义出来是在实例化的过程中是用d1初始化d5用一个对象初始化一个对象用的是拷贝构造。
下面我们利用运算符重载实现一个计算日期的小程序小程序的功能包括日期天数日期天数日期-天数日期-天数日期的前置后置日期的前置--后置--日期-日期相差多少天下面先展示源代码然后我们一个函数一个函数讲解
0,31,28,31,30,31,30,31,31,30,31,30,31
--d2;d1.Print();d2.Print();*///d2.Print();//cout
首先我们在构造函数中初始化的时候要确保日期是合法的不能出现月数小于0或者大于12的并且天数要大于0小于当月最大天数所以我们在构造函数中加了一个判断当日期不合法时就输出日期不合法并且退出程序。
0,31,28,31,30,31,30,31,31,30,31,30,31
因为我们计算日期的时候必须知道每个月是多少天而且还有闰年二月是29天的情况所以我们写了一个函数得到每个月的天数数组有13个是因为数组是从0开始我们为了方便直接在第一个位置加一个0即可。
在这里由于不确定要加多少天如果加1000天那么就要重复上图的步骤所以这是一个循环当天数大于当月最大天数的时候就进入循环需要注意的是当月数加到13就说明越界了要及时改为合法月数。
因为就是会改变本身的值并且在函数结束后日期也没有被销毁所以我们采用传引用的方式减少拷贝构造的消耗。
判断天数是否小于0是因为我们不知道有人会不会写成-数如果是负数那就是-一个正数。
日期天数那么是不会改变本身的所以我们需要拷贝构造一个变量这时候直接复用操作符即可由于tmp是函数中的临时变量函数结束就会销毁所以不能采用传引用的方式。
后置是先使用再也就是说我们必须用一个变量接收开始的日期然后自己1返回开始没有1的那个值即可由于这个值是临时变量所以只能用传值返回。
需要注意的是编译器区分前置和后置的点是后置的参数有一个int这个int是占位符没有实际作用也不用写参数写一个int即可。
需要注意的是减去天数后如果大于0就说明本月的天数够用不需要向上个月借等于0也需要借因为没有2月0日为了让借到的天数是上个月的所以月份--后再加上借的天数与同理都要判断day是否为负数为负数就变成了上一个正数那为什么和-我们没有判断呢因为和-我们是用和-复用的。
日期相减实现起来也很简单我们以之前的为负以后的为正先定义两个变量Max和Min来存放两个日期我们默认是第一个日期大于第二个日期当第一个大于第二个日期的时候就说明是之前的那么让flag为负如果第一个日期小于第二个日期就让flag为正。
然后我们用n来记录天数当两个日期不相等就进入循环让n和小的那个日期自加直到相等我们就能计算出有多少天了。
那么我们每次调用函数去打印日期是不是不方便呢能不能直接用cout打印日期呢答案是可以的我们通过重载运算符即可完成。
我们现在类中声明然后再类外实现。
我们只能通过调用函数的方式去调用和我们想的并不一样这怎么办呢我们用cout不能直接调用的原因是操作符的左边是左操作数右边是右操作数而我们常用的打印习惯是右操作数那么我们先来看一下左操作数是否能正确调用
我们发现是可以正确调用的但是很奇怪我们喜欢写到右边。
解决这个问题之前我们要先知道运算符重载在类中第一个操作符是*this而像我们那样的写法很明显out是右操作数了我们要的是out去作为左操作数想要让out成为左操作数将运算符重载写到外面了不就解决了吗因为外面是没有*this的。
但是当我们写到定义在类外发现不能访问类内的成员了这里的解决方式有多个我们讲两个简单的即可第一个将类内私有改为公有如下图
第二个是用友元函数我们将这个函数设为类的友元就可以访问类的所有成员了。
为什么编译器的cout支持多个打印我们的不可以呢这是因为我们没有返回值我们应该要将out返回这样就能连续打印了因为out出了作用域没有被销毁所以我们可以返回其引用。
这样就解决了打印自定义类型的问题接下来我们再重载一下cin与cout一样只需要改一下参数即可。
为什么输入的参数d我们不加const了呢这是因为我们输入会改变const的值如果加了const就不能改变了。
在这里需要注意一下类里面的短小函数适合做内联的函数直接是在类里面定义的。
将const修饰的“成员函数”称之为const成员函数const修饰类成员函数实际修饰该成员隐含的this指针表明在该成员函数中不能对类的任何成员进行修改。
所以这里是权限的放大想要解决只需要给this指针也用const修饰如下图
这里函数后面的const修饰的是this指针让this指针变成了const
而上图是权限的缩小权限的缩小是没有问题的调用Func函数从A*变成了const
总结内部不改变成员变量的成员函数最好加上constconst对象和普通对象都可以调用比如下面的代码
取地址重载和赋值运算符重载一样都会由编译器自己生成当然有需求也可以自己去写。
本来自定义类型用运算符必须自己重载但是赋值运算符和取地址重载编译器生成的就够用。
当然如果我们不想让别人获取我们的地址我可可以返回一个假地址如上图所示
以上就是取地址重载的用法总之不是非常必要是不用去自己写取地址重载和const取地址重载的。
学会运算符重载是学习c必备的技能c独特的就是自定义类型而运算符重载可以解决自定义类型使用运算符的问题。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback