《21天学通C++》(第十二章)运算符类型与运算符重载

ops/2024/9/24 16:27:04/

1.为什么要重载运算符?

通过重载运算符,可以将复杂的操作封装成简单的运算符形式,简化代码,提高可读性下面举一个简单的例子

计算两个点的坐标之和。

1.不重载运算符

#include <iostream>  
using namespace std; class Point { 
public:int x, y;  // Point类的成员变量,表示点的x和y坐标// 构造函数,初始化x和y坐标Point(int x, int y) : x(x), y(y) {}// 成员函数,用于计算两个点的坐标之和并返回新的Point对象Point add(const Point& other) const {return Point(x + other.x, y + other.y);  // 返回一个新Point,其坐标为当前对象和other对象坐标的和}
};int main() {Point p1(1, 2);  // 创建一个Point对象p1,坐标为(1, 2)Point p2(3, 4);  // 创建另一个Point对象p2,坐标为(3, 4)// 使用成员函数add来计算两个点的坐标之和,并将结果赋值给p3Point p3 = p1.add(p2);// 使用cout输出p3的坐标,格式为"(x, y)"cout << "The sum of p1 and p2 is: (" << p3.x << ", " << p3.y << ")" << endl;system("pause");return 0; 
}

2.使用重载运算符

#include <iostream> 
using namespace std; class Point { 
public:int x, y; // 构造函数,用于初始化点的x和y坐标Point(int x, int y) : x(x), y(y) {}// 重载 "+" 运算符,使其能够用于Point类的对象// 这个函数接受一个Point对象作为参数,并返回一个新的Point对象// 新对象的坐标是原两个Point对象坐标的和Point operator+(const Point& other) const {return Point(x + other.x, y + other.y); // 返回一个新的Point对象,其坐标为当前对象和other对象坐标的和}
};int main() {Point p1(1, 2);  // 创建一个Point对象p1,其坐标为(1, 2)Point p2(3, 4);  // 创建另一个Point对象p2,其坐标为(3, 4)// 使用重载的 "+" 运算符来计算两个Point对象的坐标之和// 这行代码等价于调用 p1.add(p2),但由于运算符重载,我们可以直接使用 + 号Point p3 = p1 + p2;cout << "The sum of p1 and p2 is: (" << p3.x << ", " << p3.y << ")" << endl;system("pause");return 0; 
}

重载运算符后可以使用+来进行坐标点的运算,代码更加简洁,可读性更高

2.单目运算符

即只能对一个操作数进行操作

单目运算符的类型
在这里插入图片描述
单目递增与单目递减运算符
一个可以对日期进行递增和递减的操作,代码如下:

#include <iostream>
using namespace std;class Date {
private:int day;int month;int year;// 简化版的日期合法性检查void checkDate() {// 如果是2月28日,增加到3月1日if (month == 2 && day == 29) {day = 1;month = 3;}// 如果月份超过12,增加年份if (month > 12) {month = 1;year++;}}public:// 构造函数Date(int d, int m, int y) : day(d), month(m), year(y) {checkDate();}// 单目递增运算符重载Date& operator++() {day++;checkDate();return *this;}// 成员函数用于输出日期void diplayDate() const {cout << day << "/" << month << "/" << year;}
};int main() {Date today(28, 2, 2024); // 今天是2024年2月28日today.diplayDate(); // 使用成员函数输出日期cout << endl; // 输出换行++today;       // 使用重载后的递增运算符today.diplayDate(); // 使用成员函数输出日期cout << endl; // 输出换行system("pause");return 0;
}

PS: 还可以使用后缀运算符,但如果只是想执行递增递减运算,应当选择前缀运算符。
因为在后缀运算符中,首先会复制当前对象,再对当前对象执行递增递减运算,最后返回复制对象,会多一步临时拷贝的步骤,且这个创建的临时拷贝也不会被使用

3.转换运算符

示例代码如下:

#include <iostream>
#include <sstream>
#include <string>
using namespace std;class Date {
private:int day;int month;int year;string dateInString; // 用于存储格式化后的日期字符串// 简化版的日期合法性检查void checkDate() {// 如果是2月28日,增加到3月1日(这里不考虑闰年)if (month == 2 && day == 29) {day = 1;month = 3;}// 如果月份超过12,增加年份if (month > 12) {month = 1;year++;}}public:// 构造函数,初始化日期并检查合法性Date(int d, int m, int y) : day(d), month(m), year(y) {checkDate();}// 单目递增运算符重载,将日期递增一天Date& operator++() {day++;checkDate();return *this;}// 类型转换运算符,将Date对象转换为const char*类型// 这样,Date对象可以直接被ostream类使用,如coutoperator const char* (){// 使用ostringstream将日期转换为字符串ostringstream oss;oss << month << "/" << day << "/" << year;// 将转换后的字符串存储在dateInString中dateInString = oss.str();// 返回字符串的C风格字符数组(const char*)return dateInString.c_str();}
};int main() {Date today(28, 2, 2024); // 使用类型转换运算符将Date对象转换为const char*,并使用cout输出cout << "Tomorrow's date: " << today << endl;system("pause");return 0;
}

通过类型转化后,可以使用cout直接输出

4.双目运算符

可以对两个操作数进行操作的运算符
在这里插入图片描述

5.函数运算符operator()

函数运算符允许类的实例表现得就函数一样,可以接受参数返回结果

#include <iostream>
#include <string>class SimpleFunc {
public:// 重载()运算符,使其可以像函数一样被调用int operator()(int a, int b) {return a + b; // 这里我们简单地返回两个数的和}
};int main() {SimpleFunc func; // 创建SimpleFunc的实例// 使用SimpleFunc实例来计算两个数的和int result = func(3, 5); // 调用func对象,传入3和5作为参数// 输出结果std::cout << "The sum of 3 and 5 is: " << result << std::endl;system("pause");return 0;
}

6.移动构造函数和移动赋值运算符

移动构造函数和移动赋值运算符是性能优化功能,用于高性能编程,属于C++11标准的一部分,旨在避免复制不必要的临时值

移动构造函数: 移动构造函数是一个接受一个同类型对象的右值引用作为参数的构造函数。它的主要目的是在对象的构造过程中,将资源从另一个对象“移动”过来,而不是进行复制

class MyClass {
public:MyClass(MyClass&& other) noexcept {//声明方法// 移动资源}
};

移动赋值运算符: 移动赋值运算符是一个接受一个同类型对象的右值引用作为参数的赋值运算符。它允许一个对象通过接管另一个对象的资源来改变其状态,而不是通过复制

class MyClass {
public:MyClass& operator=(MyClass&& other) noexcept {//声明方法// 移动资源并赋值return *this;}
};

7.不能重载的运算符

在这里插入图片描述


http://www.ppmy.cn/ops/34497.html

相关文章

病毒防护的基础知识

目录 1.震网病毒Stuxnet是蠕虫病毒 2.宏病毒Macro virus 3.X卧底Phishing 4.钓鱼网站 5.病毒类型 1.震网病毒Stuxnet是蠕虫病毒 Stuxnet蠕虫病毒&#xff08;超级工厂病毒&#xff09;是世界上首个专门针对工业控制系统编写的破坏性病毒&#xff0c;能够利用对windows系统…

R-Tree: 原理及实现代码

文章目录 R-Tree: 原理及实现代码1. R-Tree 原理1.1 R-Tree 概述1.2 R-Tree 结构1.3 R-Tree 插入与查询 2. R-Tree 实现代码示例&#xff08;Python&#xff09;结语 R-Tree: 原理及实现代码 R-Tree 是一种用于管理多维空间数据的数据结构&#xff0c;常用于数据库系统和地理信…

批量编辑管理文本,轻松修改多处内容并转换编码,提升工作效率!

在信息爆炸的时代&#xff0c;文本处理成为了我们日常工作中不可或缺的一部分。然而&#xff0c;面对大量的文本内容&#xff0c;如何高效地进行批量编辑、修改和编码转换&#xff0c;成为了许多人的难题。今天&#xff0c;我要向大家推荐一款强大的文本处理工具——文本处理专…

OpenCV在计算机视觉中的应用

OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个广泛使用的开源计算机视觉库&#xff0c;旨在提供丰富的图像和视频处理功能。它最初由Intel于1999年开发&#xff0c;并演变成为一个全球性的开源项目&#xff0c;得到了众多开发者的贡献和支持。Open…

Android getevent命令详细分析

在调试Android 的输入事件时&#xff0c;经常使用 “getevent -lrt” 命令&#xff0c;来确认驱动上报数据是否正常。从源码的角度来详细的分析一下getevent 这个程序。 首先用ls命令来看一下getevent lrwxr-xr-x 1 root shell 7 2023-11-20 10:08 system/bin/getevent -> …

详细介绍SQL语句

SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;是用于管理&#xff08;如检索、插入、更新和删除&#xff09;关系数据库中的数据的标准编程语言。以下是对SQL语句的详细介绍&#xff1a; 1. SQL语句的分类 数据定义语言&#xff08;DDL&a…

XSS Challenges 靶场通关解析

前言 XSS Challenges&#xff08;跨站脚本攻击挑战&#xff09;是一种用于学习和测试跨站脚本&#xff08;XSS&#xff09;漏洞的实验性平台。这些挑战旨在帮助安全研究人员和开发人员了解XSS漏洞的工作原理、检测方法和防御技巧。 通常&#xff0c;XSS Challenges平台提供一…

前端开发中的组件是什么

在前端开发中&#xff0c;组件指的是一种可重用的、独立的模块&#xff0c;用于构建用户界面的一部分。 组件可以是按钮、输入框、导航栏、列表等各种UI元素&#xff0c;也可以是更复杂的功能模块&#xff0c;如轮播图、模态框、表单验证等。组件化是现代前端开发的重要概念&a…