Re:从零开始的 C++ 入門篇(六)类和对象·第三篇:运算符重载

Re:从零开始的 C++ 入門篇(六)类和对象·第三篇:运算符重载

◆ 博主名称: 晓此方-ZEEKLOG博客

大家好,欢迎来到晓此方的博客。

⭐️C++系列个人专栏:

此方带你玩转C++_晓此方的博客-ZEEKLOG博客

 ⭐️踏破千山志未空,拨开云雾见晴虹。 人生何必叹萧瑟,心在凌霄第一峰


目录

0.1概要&序論

一,运算符重载

1.1运算符重载的意义

1.1.1运算符重载应当有意义

1.2运算符重载的定义

1.3运算符重载的创建

1.3.1以Date类为例

1.3.2创建重载运算符“==”

1.3.3无意义创建避免

1.4运算符重载的调用

1.4.1显式调用

1.4.2隐式调用

1.4.3重载为成员函数的调用

1.4.4调用常见问题:访问限制

1.4.5运算符重载调用优先级

1.5五大不可重载运算符

1.6指向成员变量或成员函数的指针(加餐内容)

1.6.1补充一:成员函数指针

1.6.2补充二:成员函数指针重命名

1.6.3补充三:定义成员函数指针类型变量

1.6.4补充四:用成员函数指针回调


0.1概要&序論

         みなさん、久しぶりです!,这里是此方,好久不见!上一篇我们介绍了类的默认成员函数:构造函数和析构函数。本期此方将为大家带来运算符重载的系统讲解。每一个成功的人都有一段不为人知的时光,这段时光称为”修炼“。加油!类与对象中相对困难的部分即将告一段落啦!


一,运算符重载

1.1运算符重载的意义

       运算符都是针对内置类型的,对自定义类型而言,不能简单使用运算符。这样,对于自定义类型的各种运算将无从入手。于是C++增加了运算符重载的概念。

        当运算符被用于类类型的对象时,C++语言允许我们通过运算符重载的形式指定新的含义。C++规定类类型对象使用运算符时,必须转换成调用对应运算符重载,若没有对应的运算符重载,则会编译报错。

1.1.1运算符重载应当有意义

         一个类需要重载哪些运算符,是看哪些运算符重载后有意义,比如Date类重载operator-就有意义(了解两个日期之间间隔天数),但是重载operator+就没有意义

1.2运算符重载的定义

  • 运算符重载是具有特殊名字的函数,他的名字是由operator和后面要定义的运算符共同构成。和其他函数一样,它也具有其返回类型和参数列表以及函数体。(前面的流插入流提取。就是一种内置的运算符重载)
  • 重载运算符函数的参数个数和该运算符作用的运算对象数量一样多。一元运算符有一个参数,二元运算符有两个参数,二元运算符的左侧运算对象传给第一个参数,右侧运算对象传给第二个参数。
  • 万不可连接运算符中不存在的符号进行重载:如operator@。
  • 运算符重载和函数重载没有任何关系,但是两个及以上的运算符重载构成函数重载。

1.3运算符重载的创建

1.3.1以Date类为例

class Date{ pubilc: Date(int year,int month,int day) { _year=year; _month=month; _day=day; } private: int _year; int _month; int _day; }

1.3.2创建重载运算符“==”

      要让d1==d2,就让d1的所有成员变量==d2所有成员变量。返回值设置为bool类型。传递参数两个Date类类型。

bool opreator==(Date d1 ,Date d2) { if( d1._year==d2._year &&d1._month=d2._month &&d1._day=d2._day) return true; else return false; }

1.3.3无意义创建避免

        重载操作符至少有一个类类型参数,不能通过运算符重载改变内置类型对象的含义来构建防御性变编程,如:

int operator+ (int x, int y) { return x-y; }

1.4运算符重载的调用

1.4.1显式调用

直接把重载后的运算符看作是一个函数,传入参数,如下:

int main() { Date d1(2025,2,23); Date d2(2025,3,26); operator==(d1,d2); return 0; }

1.4.2隐式调用

把重载后的运算符看作兼容该类类型的运算符,采用运算符语法。

对于二元运算符重载:左侧对象传给第一个参数,右侧传输给第二个参数。隐式调用实际上等同于显式调用,会自动转化为显示调用。
d1==d2;

1.4.3重载为成员函数的调用

下文会讲为什么会重载成成员函数,这里介绍重载为成员函数后的特殊调用方法

       如果一个重载运算符函数是成员函数,则它的第一个运算对象默认传给隐式的 this 指针,因此运算符重载作为成员函数时,参数比运算对象少一个。

class Date{ pubilc: bool opreator==(Date d){ if( _year==d._year &&_month=d._month &&_day=d._day ) return true; else return false; } //........ }

显示与隐式调用:

        隐式调用方式不变,他会自动转换成显示调用,d1传递给this指针,d2传递给d

int main() { Date d1(2025,2,23); Date d2(2025,3,26); d1.operator==(d2); d1==d2; return 0; }

1.4.4调用常见问题:访问限制

由于类的成员变量被private修饰,无法在类外直接调用。

解决办法:

最挫的方法:成员变量公有化仿JAVA常用方法:由类提供get()函数后面会讲:友元函数 最好的方法:重载为成员函数

方法一:去掉private修饰,让public修饰的作用域覆盖成员变量不建议,会让类属性被随意修改。

class Date{ pubilc: Date(int year,int month,int day){ _year=year; _month=month; _day=day; } //private: int _year; int _month; int _day; }

方法二:由类提供get()函数,在对象外调用getyear就可以通过返回值间接得到_year。

int Getyear() { return _year; }

方法四:重载为成员函数,省去一切麻烦,最推荐使用该方法,大部分的运算符重载函数都是会设计成成员函数。

class Date{ pubilc: bool opreator==(Date d2){ if( _year==d2._year &&_month=d2._month &&_day=d2._day ) return true; else return false; } private: int _year; int _month; int _day; };

1.4.5运算符重载调用优先级

//.......... bool operator==(const Date& d){ return _year == d._year && _month == d._month && _day == d._day; } //private: int _year; int _month; int _day; }; bool operator==(const Date& d1, const Date& d2){ return d1._year == d2._year && d1._month == d2._month && d1._day == d2._day; }

如果在类的内部和外部同时创建一个相同的运算符重载。

  1. operator==(d1,d2)显式调用只会调用全局函数。
  2. d1==d2隐式调用对调用成员函数还是全局函数会进行重载决议但往往成员函数会获胜

1.5五大不可重载运算符

  1. 域访问限定符。”::“
  2. 计算类型大小。“sizeof”
  3. 三元操作符。“?:”
  4. 类访问操作符。“.“
  5. 指向成员变量或成员函数的指针。”.*“
原因:

         这五个运算符被语言标准明确规定为不可重载,原因并不是随意的,而是出于语法完整性、可解析性以及编译期语义安全的系统性考虑。可以从一个统一的原则来理解:

凡是参与“语言语法结构本身”或“编译期语义建模”的运算符,都不可重载。

1.6指向成员变量或成员函数的指针(加餐内容)

       上文提到过”.*“这个运算符,想必大家都比较陌生,这是C++相比C语言新增的内容。以下给出详细介绍:

1.6.1补充一:成员函数指针

C/C++中一般函数指针举例:

void (*)(int a,int b);

成员函数指针类型:加上了域访问限定符,标志该函数指针来自哪里,是什么类的成员函数。

void (A::*)(int a,int b);

1.6.2补充二:成员函数指针重命名

重命名:注意函数指针类型的重命名相比一般重命名不同:这里将void (*)(int a,int b)重命名为PF

typedef void (*PF)(int a,int b);

C/C++中成员函数指针重命名:

typedef void (A::*PF)(int a,int b);

1.6.3补充三:定义成员函数指针类型变量

定义一个成员函数指针类型的变量:

void (A::*pf)(int a,int b)=nullptr;//方法一 PF pf=nullptr;//方法二

1.6.4补充四:用成员函数指针回调

       取得现有成员函数的指针,与普通函数指针不同,成员函数的指针取得,需要加上两个步骤:确定类域和取地址。

pf=&A::func;

回调函数:一般函数的回调方式:

pf=func(); //将函数的指针放入函数指针变量中。 *pf() //取地址函数指针变量进行回调

        成员函数由于函数的第一个参数是this指针,但是this指针不能显示传参,所以要一个对象进行辅助,用这个对象调用这个函数。

A aa; (aa.*pf)()

于是,就出现了.*运算符。

        成员函数的回调在日常代码中使用的非常非常少。C语言时期学过的qsort函数就是用回调的,后面C++还有很多更好的解决办法,一般的,我们会尽可能避免使用函数指针

好了,本期内容就到这里,我是此方,我们下期再见。じゃあね〜

Read more

用飞算JavaAI做项目:在线图书借阅平台设计与实现

用飞算JavaAI做项目:在线图书借阅平台设计与实现

目录 * 一、引言 * 二、环境准备 * 1. 下载并安装IntelliJ IDEA * 2. 安装飞算JavaAI插件 * 3. 登录飞算JavaAI * 三、模块设计与编码 * 1. 飞算JavaAI生成基础模块 * 2. 核心代码展示 * (1)entity包:核心实体类 * (2)dto包:数据传输对象(带参数校验) * (3)vo包:视图对象(向前端隐藏敏感字段) * (4)service包:业务逻辑实现(含核心校验) * 四、网页展示 * 1. 图书查询页 * 2. 借阅记录页 * 3. 图书管理页 * 五、优化与调试 * 1. 核心优化点 * 2. 调试中遇到的问题及解决 * 六、自我感想 * 七、

By Ne0inhk

2026年 Java 面试八股文总结(完整版)

1、Java中有几种类型的流    难度系数:⭐ 2、请写出你最常见的5个RuntimeException    难度系数:⭐ 1. java.lang.NullPointerException 空指针异常;出现原因:调用了未经初始化的对象或者是不存在的对象。 1. java.lang.ClassNotFoundException 指定的类找不到;出现原因:类的名称和路径加载错误;通常都是程序试图通过字符串来加载某个类时可能引发异常。 1. java.lang.NumberFormatException 字符串转换为数字异常;出现原因:字符型数据中包含非数字型字符。 1. java.lang.IndexOutOfBoundsException 数组角标越界异常,常见于操作数组对象时发生。 1. java.lang.IllegalArgumentException 方法传递参数错误。 1. java.lang.ClassCastException 数据类型转换异常。 3、谈谈你对反射的理解    难度系数:⭐ 1. 反射

By Ne0inhk
JAVA 注解(Annotation):从原理到实战应用

JAVA 注解(Annotation):从原理到实战应用

JAVA 注解(Annotation):从原理到实战应用 1.1 本章学习目标与重点 💡 掌握注解的核心概念与分类,理解注解在Java开发中的核心价值。 💡 熟练使用JDK内置注解,掌握自定义注解的定义、解析与使用流程。 💡 掌握注解的元注解配置方式,理解不同元注解对自定义注解的约束作用。 💡 结合反射机制实现注解的实战应用,掌握注解在框架开发中的核心用法。 ⚠️ 本章重点是 自定义注解的开发流程 和 注解与反射结合的实战应用,这是Java高级开发与框架设计的必备技能。 1.2 注解的核心概念与价值 1.2.1 什么是注解 💡 注解(Annotation) 是Java 5引入的一种特殊标记,它可以在编译期、类加载期、运行时被读取,并执行相应的处理逻辑。注解本身不直接影响代码的执行逻辑,而是通过元数据的方式为程序提供额外信息,这些信息可以被编译器、虚拟机或自定义的注解处理器解析和使用。 注解的本质是一个继承了 java.lang.annotation.Annotation 接口的特殊接口,我们定义的每一个注解,最终都会被编译器生成对应的接口实现类,供程序在运行时

By Ne0inhk
Java 大视界 -- Java 大数据在智能医疗影像数据压缩与传输优化中的技术应用

Java 大视界 -- Java 大数据在智能医疗影像数据压缩与传输优化中的技术应用

Java 大视界 -- Java 大数据在智能医疗影像数据压缩与传输优化中的技术应用 * 引言: * 正文: * 一、智能医疗影像数据的「三重困境」 * 1.1 数据洪流:存储成本的指数级增长 * 1.2 实时枷锁:远程医疗的传输瓶颈 * 1.3 质量红线:压缩与保真的矛盾 * 二、Java 大数据:医疗影像压缩的「智能引擎」 * 2.1 算法精研:从传统到智能的跨越 * 2.2 动态优化:基于 AI 的智能压缩策略 * 三、Java 大数据:医疗影像传输的「加速引擎」 * 3.1 分布式架构:突破传输带宽限制 * 3.2 边缘计算:构建「

By Ne0inhk