当前位置: 首页 > news >正文

【C++】类和对象--类中6个默认成员函数(2) --运算符重载

运算符重载

为了增强代码的可读性,C++中引入了运算符重载的概念,运算符重载是一种有着特殊函数名的函数:

  • 函数名字:关键字operator+ 需要重载的运算符符号
  • 函数原型返回值类型 operator+操作符(参数列表)

我们接下来使用一个Date类来进行说明:

代码语言:javascript

AI代码解释

class Date { public: Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; }; int main() { Date d1(2025, 8, 6); Date d2(2025, 8, 6); if (d1 == d2) { cout << "==" << endl; } return 0; }

我们正常的想法,不就是通过运算符==来比较两个变量的大小嘛,那么上面的代码能不能正常运行呢?

答案是:不行的

原因:只有内置类型的变量才能使用各种运算符,对于Date这种我们自定义类型的的对象是不能直接使用的。而为了是的自定义类型对象能够使用这些运算符,C++给出了运算符重载的概念。

注意:这里的运算符重载和之前我们学习的函数重载是不一样的!函数重载是函数名相同但参数列表不同,而运算符重载是我们重新定义运算符的规则和意义。

这里C++给出了一个关键字operator,后面加上运算符,称作函数运算符重载。

然后我们还是通过上面Date d1、d2比较的例子来对此进行说明,例如我们这里将==运算符重载:

代码语言:javascript

AI代码解释

operator==(参数1,参数2)

同时这里还有一件事情值得注意!就是运算符重载的参数列表,是由该运算符的操作数决定的,例如:++只需要一个操作数(所以重载++的参数列表只需要一个参数)、但是<、<<、!=都需要两个操作数(所以这些运算符重载的参数列表需要两个参数)。

所以我们最后以代码形式呈现就是这样:

代码语言:javascript

AI代码解释

bool operator==(Date d1, Date d2) { return d1._year == d2._year && d1._month == d2._month && d1._day == d2._day; }

但是我们发现:

这是因为Date类中的成员变量都是private私有的,不能被类外访问,当然这个问题很好解决,我们甚至有很多解决方法:

  • 将成员变量改成public公有的(但是这种方法显然不好)
  • 提供函数接口(也就是说,在类中写一个函数,拿到私有的成员变量,然后类外调用函数,太麻烦)
  • 友元(会破坏封装,之后会学到)
  • 将函数放在类中(这个方法是常用的方法)

这里我们先使用第一种方法试试:

代码语言:javascript

AI代码解释

#include <iostream> using namespace std; class Date { public: Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } //我们这里将成员变量改成公有的 //private: int _year; int _month; int _day; }; bool operator==(Date d1, Date d2) { return d1._year == d2._year && d1._month == d2._month && d1._day == d2._day; } int main() { Date d1(2025, 8, 6); Date d2(2025, 8, 6); if (d1 == d2) { cout << "==" << endl; } return 0; }

运行结果:

当然是能够成功编译的。

接下来我们重点试一下最后一种方法,将运算符重载放在类中:

但令人奇怪的是,报错了!!!

可是按照逻辑,我们确实应该传入与运算符操作数一样数量的参数,那为什么会报错呢?

原因:

这里其实并不只是两个参数,其实是三个参数。这里我们需要回顾一下我们之前在学习this指针的相关知识,当函数定义在类内部(换句话说一个函数是成员函数)那么就会自带一个this指针。而这里报错的参数过多,就是因为将this统计在内。所以使用最后一种方法,我们只需要传入一个参数,像下面这样:

代码语言:javascript

AI代码解释

class Date { public: Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } //注意这里的变化!!! bool operator==(Date d) { return _year == d._year && _month == d._month && _day == d._day; } private: int _year; int _month; int _day; }; int main() { Date d1(2025, 8, 6); Date d2(2025, 8, 6); if (d1 == d2)//编译器会处理成对应重载运算符调用 if (d1.operator(d2)) { cout << "==" << endl; } return 0; }

这时我们编译成功:

然后我们来解释一下这里的调用逻辑:

实际上在使用重载后的==进行比较时,编译器会处理成运算符重载的调用

但是上述我们使用的都是传值传参,都会调用拷贝构造函数。所以我们更好的方法是使用传引用传参,如果不改变的话最后再加上const:

代码语言:javascript

AI代码解释

bool operator==(const Date& d) { return _year == d._year && _month == d._month && _day == d._day; }

注意:

  • 不能够使用opeartor+其他符号来定义新的运算符,比如:operator@
  • 运算符重载必须要有一个类类型或枚举类型的参数
  • 当运算符重载作为类成员时,参数列表会看起来比运算符操作数少1,这是因为额外传入了this指针
http://www.jsqmd.com/news/454478/

相关文章:

  • 2026年环保透气不闷汗床垫推荐:五款深度横评,帮你找到会“呼吸”的健康好床垫 - 资讯焦点
  • Zero Autonomous Thinking:面向OpenClaw的自主意识智能体框架
  • Spring中的IOC详解
  • Linux内核驱动开发“武功秘籍”——金庸与古龙江湖的修炼之道
  • 2026年NMN十大品牌排行榜:哪个品牌效果最好?口碑、性价比全对比 - 资讯焦点
  • 梅森素数VS是(四)素数
  • SpringSecurity之跨域
  • 从0开始学习C++:C/C++ 输入输出全攻略
  • SpringMVC的工作流程
  • 国内信创实时云渲染服务商怎么选?靠谱标准看这几点
  • C++ 手写实现 unordered_map 和 unordered_set:深入解析与源码实战
  • 【Linux系统】进程状态 | 进程优先级
  • 中小企业布局信创实时云渲染,可行吗?
  • C++ 定长内存池,让内存分配快到飞起!
  • 信创实时云渲染与传统本地渲染,企业选型该瞄准哪些核心点?
  • 【毕业设计】SpringBoot+Vue+MySQL 医院信管系统平台源码+数据库+论文+部署文档
  • SpringBoot+Vue 智能菜谱推荐系统管理平台源码【适合毕设/课设/学习】Java+MySQL
  • C++ 异常处理机制详解:从基础语法到工程实践
  • 2026年江苏变压器铜铝排/变压器铜电磁线/变压器铝电磁线服务商采购白皮书:高压输配电领域的核心供应商竞争力解析 - 2026年企业推荐榜
  • Flutter 三方库 ntp_dart 的鸿蒙化适配指南 - 获取绝对可信的授时服务、助力鸿蒙端金融与考勤类应用杜绝本地时钟作弊风险
  • 【Linux系统】理解硬件 | 引入文件系统
  • 《Linux 输入输出重定向与 VI 编辑器:全面操作指南与原理剖析》
  • Spring推出Spring AI框架,看看怎么个事
  • 2026年无纸化会议系统推荐指南:会议音响套装/吸顶会议音箱/国产无纸化会议/多媒体室音响/大礼堂音响/选择指南 - 优质品牌商家
  • 【Linux系统】进程地址空间
  • Linux网络编程:应用层自定义协议与序列化
  • 2026年外贸建站公司实力大盘点:口碑、技术、信用TOP级企业全解析 - 品牌推荐大师1
  • 年度总结:我的技术成长与反思
  • 【Linux系统】命令行参数和环境变量
  • 核“芯”动力,重构无人机通信边界——LR1121IMLTRT 多频段LoRa收发器