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

《Beginning C++20 From Novice to Professional》第十三章 Operator Overloading

操作符重载主要是让自定义类型有和内置类型类似的自然的操作,比如字符串的连接、矩阵的运算等等用操作符比使用成员函数(虽然也是成员函数)要直观一些

本章我们可以学到:

Implementing Operators for a Class

上一章我们实现的Truckload类有一个寻找最大体积的函数,其中有段逻辑是这样的:

比较两个数我们会自然地想到数学里的<>=运算符,而不是使用成员函数compare然后拿返回值和0比较,所以能不能写成下面这样的形式呢?

再比如两个盒子体积相加、相乘等类数学运算操作,如果写成数学表达式的形式会更有可读性

Operator Overloading 操作符重载

实际上string类里就有很多重载的操作符,比如+用来连接两个string,或者==来判断两个字符串是否相同,如果像这样设计的好,操作符重载可以让我们不加思考地写出非常优雅的代码

操作符函数本身也是函数,和普通函数不一样的地方在于,我们实现自己的版本时需要加上operator这个关键字

Implementing an Overloaded Operator

让我们来看个例子:

因为是比较,所以小于操作符函数的返回类型应该是bool;这里参数表示的是操作符的第二个操作对象,假如a<b,那么相当于a.operator<(b),a是调用这个成员操作符函数的对象,b就是这个函数的参数;const不多说了,比较操作应该对对象数据是只读的

然后用了这个形式(先不管实现),我们就可以写成下面的比较

书中也提供了一幅图来说明上面的过程,还提供了实现(就一行)

下面代码用来验证重载的比较操作

注意我们的smallBox是用来存储最大值的对象,在循环过程中只要发现有比之前大的就重新赋值,这里的=其实也是一个操作符,但是我们并没有实现,因为编译器默认给所有类生成一个赋值运算符函数,把右侧对象给复制到左边,行为就像复制构造函数

但是这个默认赋值操作有时候并不能完全满足实际需要,后面的小节里我们会说到这个问题

Nonmember Operator Functions

#include <iostream>
#include <vector>
using namespace std;

class Box {
	public:
		// Constructors
		Box() = default;

		Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h} {}

		double volume() const { return m_length * m_width * m_height; }

		// Accessors
		double getLength() const { return m_length; }

		double getWidth() const { return m_width; }

		double getHeight() const { return m_height; }

	private:
		double m_length{1.0};
		double m_width{1.0};
		double m_height{1.0};
};

bool operator<(const Box& box1, const Box& box2) { return box1.volume() < box2.volume(); }

int main() {
	std::vector boxes{Box{2.0, 2.0, 3.0},
					  Box{1.0, 3.0, 2.0},
					  Box{1.0, 2.0, 1.0},
					  Box{2.0, 3.0, 3.0}
	};
	Box smallBox{boxes[0]};
	for (const auto& box: boxes) {
		if (box < smallBox)
			smallBox = box;
	}
	std::cout << "The smallest box has dimensions "
			<< smallBox.getLength() << 'x'
			<< smallBox.getWidth() << 'x'
			<< smallBox.getHeight() << std::endl;
}

对于<这样的两元运算符,一般还是重


http://www.kler.cn/a/403977.html

相关文章:

  • Docker 容器的初始化设置
  • 【PCIE常见面试问题-1】
  • 案例精选 | 某知名教育集团基于安全运营平台的全域威胁溯源实践
  • ESP32桌面天气摆件加文心一言AI大模型对话Mixly图形化编程STEAM创客教育
  • 三种复制只有阅读权限的飞书网络文档的方法
  • Elasticsearch 中的热点以及如何使用 AutoOps 解决它们
  • 泷羽sec----shell编程(7)
  • 什么是React Native?
  • 使用node-addon-api实现从c到nodejs模块全流程
  • 26届JAVA 学习日记——Day14
  • 【学习笔记】AD智能PDF导出(装配文件)
  • React的API✅
  • reactflow 中 useReactFlow 模块作用
  • IDEA 2024安装指南(含安装包以及使用说明 cannot collect jvm options 问题 四)
  • Ubuntu 18.04 安装 Docker
  • ubuntu中使用ffmpeg和nginx推流rtmp视频
  • 大数据新视界 -- Hive 数据仓库:架构深度剖析与核心组件详解(上)(1 / 30)
  • 电源模块自动化测试系统的优势体现在哪些方面?-纳米软件
  • 科技赋能健康:多商户Java版商城系统引领亚健康服务数字化变革
  • uniapp奇怪bug汇总
  • Java项目实战II基于Spring Boot的工作流程管理系统设计与实现(开发文档+数据库+源码)
  • 图像处理 - 色彩空间转换
  • Dockerfile复制目录进入镜像里
  • 主机管理工具 WGCLOUD v3.5.6 更新了哪些特性
  • 注意原函数平行,取log后就不平行了
  • 晶圆测试中自动化上下料的重要性与应用