【C++指南】运算符重载详解

引言

C++ 提供了运算符重载这一特性,允许程序员为自定义类型(如类和结构体)定义运算符的行为

通过运算符重载,可以使自定义类型对象像内置类型一样使用运算符,从而提高代码的可读性和易用性。

本文将详细介绍 C++ 中运算符重载的概念、语法、规则、注意事项以及实际应用。

 

目录

引言

 🍃运算符重载的概念

🍃运算符重载的语法

🍃可重载的运算符

🍃运算符重载的规则

🍃运算符重载的实现

🍃注意事项

🍃实际应用

示例代码

运算符重载的应用项目:日期类实现

结语


 🍃运算符重载的概念

运算符重载是指为类(或结构体)的特定运算符提供自定义实现,使其能够作用于类的对象。重载的运算符可以保持其原有的语义,也可以定义新的语义。

C++规 定类类型对象使⽤运算符时,必须转换成调⽤对应运算符重载,若没有对应的运算符重载,则会编译报错。

🍃运算符重载的语法

  • 运算符重载通过成员函数或友元函数来实现。
  • 运算符重载是具有特殊名字的函数,他的名字是由operator和后⾯要定义的运算符共同构成。
  • 和其他 函数⼀样,它也具有其返回类型和参数列表以及函数体。
  • 如果⼀个重载运算符函数是成员函数,则它的第⼀个运算对象默认传给隐式的this指针,因此运算 符重载作为成员函数时,参数比运算对象少⼀个 

  • 成员函数形式
class MyClass {  
public:  MyClass operator+(const MyClass& other) const; // 重载加法运算符  // ... 其他成员 ...  
};
  • 友元函数形式
class MyClass {  
public:  friend MyClass operator+(const MyClass& lhs, const MyClass& rhs); // 声明友元函数  // ... 其他成员 ...  
};  // 类外部定义友元函数  
MyClass operator+(const MyClass& lhs, const MyClass& rhs) {  // 实现加法运算  
}

🍃可重载的运算符

C++ 允许重载几乎所有的运算符,但有几个运算符不能重载:  .  .*    ::    ?:   sizeof 和 typeid。这些运算符与对象的成员访问、类型信息获取等底层操作紧密相关,因此不允许重载。

🍃运算符重载的规则

  • 不能改变运算符的优先级和结合性:重载的运算符仍然保持其原有的优先级和结合性。
  • 不能改变运算符的操作数个数:例如,不能将一元运算符重载为二元运算符,反之亦然。
  • 重载的运算符不能是新的类型:重载的运算符必须是 C++ 中已定义的运算符。
  • 成员运算符函数不能有默认参数:重载的运算符函数不能有默认参数。

🍃运算符重载的实现

  • 成员函数形式:当运算符重载为成员函数时,左侧操作数必须是该类的一个对象(或引用),而右侧操作数可以是任意类型(包括内置类型和该类类型)。
  • 友元函数形式:当运算符重载为友元函数时,两个操作数可以是任意类型(包括内置类型和该类类型),这提供了更大的灵活性。

🍃注意事项

  • 避免不必要的重载:只有当运算符的默认行为不适用于自定义类型时,才考虑重载。
  • 保持语义一致性:重载的运算符应尽可能保持其原有的语义,以避免混淆。
  • 注意异常安全性:在重载运算符时,要考虑到异常安全性,确保在异常发生时不会泄露资源或破坏对象状态。
  • 实用性:⼀个类需要重载哪些运算符,是看哪些运算符重载后有意义
  • 前置++与后置++:重载++运算符时,有前置++和后置++,运算符重载函数名都是operator++,无法很好的区分。 C++规定,后置++重载时,增加⼀个int形参,跟前置++构成函数重载,方便区分
  • 重载>>和<<:需要重载为全局函数,因为重载为成员函数,this指针默认抢占了第⼀个形参位 置,第⼀个形参位置是左侧运算对象,调⽤时就变成了对象<<cout,不符合语法和习惯。重载为全局函数把ostream/istream放到第⼀个形参位置就可以了,第⼆个形参位置当类类型对象

🍃实际应用

运算符重载在 C++ 中有着广泛的应用,例如:

  • 复数类:可以重载加法、减法、乘法和除法等运算符,使复数对象能够像内置类型一样进行算术运算。
  • 点类:可以重载加法运算符来表示点的平移,重载减法运算符来表示点的距离计算等。
  • 字符串类:可以重载加法运算符来表示字符串的连接,重载比较运算符来表示字符串的大小比较等。

示例代码

以下是一个简单的复数类示例,展示了如何重载加法、减法和乘法运算符:

#include <iostream>  class Complex {  
private:  double real;  double imag;  public:  // 构造函数  Complex(double r = 0, double i = 0) : real(r), imag(i) {}  // 重载加法运算符  Complex operator+(const Complex& other) const {  return Complex(real + other.real, imag + other.imag);  }  // 重载减法运算符  Complex operator-(const Complex& other) const {  return Complex(real - other.real, imag - other.imag);  }  // 重载乘法运算符  Complex operator*(const Complex& other) const {  return Complex(real * other.real - imag * other.imag, real * other.imag + imag * other.real);  }  // 重载输出运算符  friend std::ostream& operator<<(std::ostream& os, const Complex& c) {  os << c.real << " + " << c.imag << "i";  return os;  }  
};  int main() {  Complex c1(1, 2);  Complex c2(3, 4);  Complex c3 = c1 + c2;  Complex c4 = c1 - c2;  Complex c5 = c1 * c2;  std::cout << "c1: " << c1 << std::endl;  std::cout << "c2: " << c2 << std::endl;  std::cout << "c1 + c2: " << c3 << std::endl;  std::cout << "c1 - c2: " << c4 << std::endl;  std::cout << "c1 * c2: " << c5 << std::endl;  return 0;  
}

在这个示例中,我们定义了一个 Complex 类来表示复数,并重载了加法、减法和乘法运算符,以及输出运算符。这样,我们就可以像使用内置类型一样使用 Complex 对象进行算术运算和输出。

运算符重载的应用项目:日期类实现

详细内容参考文章,点击下方链接:

【C++指南】类和对象入门实践:日期类实现-CSDN博客

结语

运算符重载是 C++ 中的一个强大特性,它允许程序员为自定义类型定义运算符的行为。通过合理地使用运算符重载,可以使代码更加简洁、易读和高效。然而,在重载运算符时,需要遵循一定的规则和注意事项,以确保代码的正确性和安全性。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/57537.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【状态机DP】力扣2786. 访问数组中的位置使分数最大

给你一个下标从 0 开始的整数数组 nums 和一个正整数 x 。 你 一开始 在数组的位置 0 处&#xff0c;你可以按照下述规则访问数组中的其他位置&#xff1a; 如果你当前在位置 i &#xff0c;那么你可以移动到满足 i < j 的 任意 位置 j 。 对于你访问的位置 i &#xff0c…

若依微服务15 - RuoYi-Vue3 实现前端独立运行

正文开始&#xff1a; RuoYi-Vue3 使用 Vue3 Element Plus Vite 技术栈。 GitHub 开源地址&#xff1a;https://github.com/yangzongzhuan/RuoYi-Vue3 本文介绍使用若依提供的在线后端接口&#xff0c;仅启动前端项目并进行界面开发&#xff0c;而无需启动后端服务。 一、克隆…

AI视听新体验!浙大阿里提出视频到音乐生成模型MuVi:可解决语义对齐和节奏同步问题

MuVi旨在解决视频到音乐生成(V2M)中的语义对齐和节奏同步问题。 MuVi通过专门设计的视觉适配器分析视频内容,以提取上下文 和时间相关的特征,这些特征用于生成与视频的情感、主题及其节奏和节拍相匹配的音乐。MuVi在音频质量和时间同步方面表现优于现有基线方法,并展示了其在风…

C++:模板的特化与分离编译

之前我们在介绍模板的时候仅仅是简单的介绍了模板的用法&#xff0c;本篇文章我们来详细的介绍下模板中比较重要的几个点。 一&#xff0c;非类型模板参数 我们之前的c中&#xff0c;会将经常使用的而又确保在我们程序的运行过程中值不会改变的值进行#define&#xff1a; #d…

初入编程之路,启航代码海

#1024程序员节|征文# 前言 今天又是1024程序员节了&#xff0c;第一次听说这个节日是在我在23年刚刚上大一的时候听学长他们说的&#xff0c;如今已经是24年了&#xff0c;虽然只学习了一年的编程但我已经了解到了这条路上的不易。希望能够在这条路上面一路坚持下去&#xff0…

力扣_斐波那契数列

本题目本质和爬楼梯是一样的&#xff0c;主要运用的是递归来解题。 class Solution:my_dict {}def fib(self, n: int) -> int:if self.my_dict.get(n) is not None: # 先判断有没有计算过这个值return self.my_dict.get(n)tempResult 0if n > 2:tempResult self.fib…

075_基于springboot的万里学院摄影社团管理系统

目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍&#xff1a;CodeMentor毕业设计领航者、全网关注者30W群落&#xff0c;InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者&#xff0c;博客领航之星、开发者头条/腾讯云/AW…

MySql中使用findInSet和collection实践

FIND_IN_SET 需求如下&#xff1a;有张用户表&#xff0c;表里有个字段叫school&#xff0c;意为这个用户上过哪些学校&#xff0c;数据库里存的就是字符串类型&#xff0c;存的值类似"2,5,12"&#xff0c;要求就是查询出上过id为2的学校有哪些用户 解决方法&#x…

【JAVA毕设】基于JAVA的酒店管理系统

一、项目介绍 本系统前端框架采用了比较流行的渐进式JavaScript框架Vue.js。使用Vue-Router实现动态路由&#xff0c;Ajax实现前后端通信&#xff0c;Element-plus组件库使页面快速成型。后端部分&#xff1a;采用SpringBoot作为开发框架&#xff0c;同时集成MyBatis、Redis、…

qt生成uuid,转成int。ai回答亲测可以

// 生成一个随机的UUID QUuid uuid QUuid::createUuid(); // 将UUID转换为字符串 QString uuidStr uuid.toString(QUuid::WithoutBraces);// 计算MD5哈希值 QByteArray hash QCryptographicHash::hash(uuidStr.toUtf8(), QCryptographicHash::Md5);// 提取前8个字节并转换为…

云曦10月13日awd复现

一、防御 1、改用户密码 passwd <user> 2、改数据库密码 进入数据库 mysql -uroot -proot 改密码 update mysql.user set passwordpassword(新密码) where userroot; 查看用户信息密码 select host,user,password from mysql.user; 改配置文件&#xff0c;将密码改为自己…

电脑技巧:Rufus——最佳USB启动盘制作工具指南

目录 一、功能强大&#xff0c;兼容性广泛 二、界面友好&#xff0c;操作简便 三、快速高效&#xff0c;高度可定制 四、安全可靠&#xff0c;社区活跃 在日常的电脑使用中&#xff0c;无论是为了安装操作系统、修复系统故障还是进行其他需要可引导媒体的任务&#xff0c;拥…

使用 Python结合随机User-Agent与代理池进行网络请求

1. 引言 在爬虫开发过程中&#xff0c;为了模拟真实的用户行为&#xff0c;避免被目标网站识别并封锁&#xff0c;通常需要使用随机的User-Agent以及代理IP来发送网络请求。本文将介绍如何通过Python实现这一功能&#xff0c;包括设置随机User-Agent、读取代理列表&#xff0c…

web网页

HTML代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>wyy</title><!-- 引…

VSCODE c++不能自动补全的问题

最近安装了vscode&#xff0c;配置了C/C扩展&#xff0c;也按照网上说的配置了头文件路径 我发现有部分头文件是没办法解析的&#xff0c;只要包含这些头文件中的一个或者多个&#xff0c;就没有代码高亮和代码自动补全了&#xff0c;确定路径配置是没问题的&#xff0c;因为鼠…

Linux笔记之文件查找和搜索命令which,find,locate,whereis总结

Linux笔记之文件查找和搜索命令which,find,locate,whereis总结 code review! 文章目录 Linux笔记之文件查找和搜索命令which,find,locate,whereis总结1.对比2.whereis 和 which 命令区别3.locate 和 find 命令区别 1.对比 命令功能说明备注which常用于查找可直接执行的命令。…

基于ssm的萌宠商城管理系统【附源码】

基于ssm的萌宠宜家商城系统&#xff08;源码L文说明文档&#xff09; 目录 4 系统设计 4.1 系统概述 4.2 系统概要设计 4.3 系统功能结构设计 4.4 数据库设计 4.4.1 数据库E-R图设计 4.4.2 数据库表结构设计 5 系统实现 5.1 管理员功能介绍 …

【C++中的lambda表达式】

不需要借口&#xff0c;爱淡了就放手....................................................................................................... 文章目录 前言 一、【lambda表达式介绍】 1、【lamda表达式的概念】 2、【lamda表达式的语法】 二、【lambda表达式的使用】…

CAS简介

#1024程序员节&#xff5c;征文# CAS是什么&#xff1f; CAS&#xff08;Compare And Swap&#xff09;&#xff0c;即比较与交换&#xff0c;是一种乐观锁的实现方式&#xff0c;用于在不使用锁的情况下实现多线程之间的变量同步。 CAS操作包含三个操作数&#xff1a;内存位…

Stability.AI 发布 SD3.5 模型,能否逆袭击败 FLUX?如何在ComfyUI中的使用SD3.5?

就在前天&#xff0c;Stability AI 正式发布了 Stable Diffusion 3.5版本&#xff0c;包括 3 款强大的模型&#xff1a; Stable Diffusion 3.5 Large&#xff1a;拥有 80 亿参数&#xff0c;提供卓越的图像质量和精确的提示词响应&#xff0c;非常适合在 1 兆像素分辨率下的专…