「C++系列」重载运算符/重载函数

news2024/9/22 1:36:10

文章目录

  • 一、重载运算符
    • 1. 运算符重载的规则
    • 2. 示例:重载加法运算符`+`
    • 3. 注意事项
  • 二、可重载运算符/不可重载运算符
    • 1. 可重载的运算符
    • 2. 不可重载的运算符
    • 3. 注意事项
  • 三、重载函数
    • 1. 函数重载的基本规则
    • 2. 示例
    • 3. 注意事项
  • 四、相关链接

一、重载运算符

在C++中,重载运算符允许你为自定义类型(如类)的实例定义运算符的行为。这意呀着你可以像使用内置类型(如int或float)那样使用你的自定义类型进行算术运算、比较、赋值等操作。重载运算符是通过在类内部或外部定义成员函数或非成员函数来实现的。

1. 运算符重载的规则

  1. 不能改变运算符的优先级:重载后的运算符优先级和结合性保持不变。
  2. 不能改变运算符的操作数个数:例如,你不能将二元运算符重载为单目运算符。
  3. 不能创建新的运算符:你只能重载C++中已有的运算符。
  4. 不能重载所有的运算符:例如,..*::?:sizeoftypeid 等运算符不能被重载。
  5. 重载的运算符可以定义为成员函数或非成员函数:但是,某些运算符(如赋值运算符=、下标运算符[]、函数调用运算符()、成员访问运算符->*->)只能作为成员函数重载。

2. 示例:重载加法运算符+

假设我们有一个简单的Point类,表示二维空间中的点,我们想要重载加法运算符,以便可以将两个Point对象相加,得到一个新的Point对象,其坐标是这两个点坐标的和。

#include <iostream>

class Point {
public:
    int x, y;

    // 构造函数
    Point(int x = 0, int y = 0) : x(x), y(y) {}

    // 重载加法运算符
    Point operator+(const Point& rhs) const {
        return Point(x + rhs.x, y + rhs.y);
    }

    // 输出函数,用于演示
    void print() const {
        std::cout << "(" << x << ", " << y << ")" << std::endl;
    }
};

int main() {
    Point p1(1, 2);
    Point p2(3, 4);

    Point p3 = p1 + p2; // 使用重载的加法运算符
    p3.print(); // 输出: (4, 6)

    return 0;
}

在这个例子中,operator+是一个成员函数,它接受一个Point类型的常量引用作为参数(rhs),并返回一个新的Point对象,该对象的坐标是调用对象(*this)和参数对象(rhs)的坐标之和。注意,我们在这里将operator+定义为const成员函数,因为我们没有修改调用对象的状态。

3. 注意事项

  • 当重载运算符时,考虑其语义是否适合你的类。
  • 运算符重载应该保持直观和易于理解。
  • 某些运算符(如赋值运算符=)可能需要返回对自身的引用(*this),以便支持链式调用。
  • 运算符重载可能会引入额外的性能开销,因为它们是函数调用。然而,在大多数情况下,这种开销是可以接受的。

二、可重载运算符/不可重载运算符

在C++中,大部分运算符都可以被重载,但也有一些运算符是不能被重载的。这些运算符的不可重载性通常是因为它们与语言的底层机制紧密相关,或者是因为它们的行为在语义上不应该被改变。

1. 可重载的运算符

大部分C++中的运算符都可以被重载,包括:

  • 算术运算符:+-*/%(取模)、++(前缀和后缀)、--(前缀和后缀)
  • 关系运算符:==!=<<=>>=
  • 逻辑运算符:&&||!(但请注意,这些运算符通常通过成员函数重载时并不直观,因为它们期望两个操作数,而成员函数重载通常只涉及一个显式的操作数——*this指针所指向的对象)
  • 赋值运算符:=+=-=*=/=%=
  • 位运算符:&|^~<<>>
  • 成员访问运算符:->*->(注意,这些运算符只能作为成员函数重载)
  • 下标运算符:[](也只能作为成员函数重载)
  • 函数调用运算符:()(也只能作为成员函数重载,用于重载对象的调用方式)
  • 逗号运算符:,(不常用,但技术上可以重载)
  • 转换运算符(类型转换运算符):用于定义对象如何被隐式或显式地转换为其他类型。

2. 不可重载的运算符

以下运算符在C++中是不可重载的:

  • . 成员访问运算符
  • .* 成员指针访问运算符
  • :: 作用域解析运算符
  • ?: 条件运算符(三元运算符)
  • sizeof 运算符(用于获取对象或类型的大小)
  • typeid 运算符(用于在运行时获取对象的类型信息)
  • const_caststatic_castdynamic_castreinterpret_cast 等类型转换运算符(尽管它们看起来像是运算符,但实际上它们是特殊的语言构造,用于执行类型转换)

3. 注意事项

  • 当重载运算符时,通常应该保持运算符的语义不变,即重载后的运算符应该执行与原始运算符相似的操作,只是针对自定义类型。
  • 重载运算符时,可以通过成员函数或非成员函数来实现。但是,某些运算符(如赋值运算符=、下标运算符[]、函数调用运算符()等)只能作为成员函数重载。
  • 重载运算符时,可以定义返回类型,但通常应该返回与操作数类型相同(或兼容)的类型,除非有特殊的理由需要返回不同类型的对象。
  • 运算符重载可以提高代码的可读性和易用性,但过度使用或不当使用可能会导致代码难以理解和维护。因此,在决定重载运算符之前,应该仔细考虑是否真的需要这样做。

三、重载函数

C++ 中的函数重载允许在同一个作用域内定义多个同名的函数,只要这些函数的参数列表(参数的类型、顺序或数量)不同即可。这样,你可以使用同一个函数名来执行不同的任务,具体执行哪个任务取决于调用函数时提供的参数。

1. 函数重载的基本规则

  1. 函数名必须相同:重载的函数必须具有相同的名称。
  2. 参数列表必须不同:这包括参数的类型、顺序或数量。仅通过返回类型的不同来区分重载函数是不允许的。
  3. 函数可以具有不同的返回类型,但返回类型不能作为重载的依据。
  4. 函数可以有不同的访问修饰符(如publicprotectedprivate),但这通常不是重载的考虑因素,因为重载是在编译时根据函数名和参数列表来确定的。
  5. 可以声明为const的函数和未声明为const的函数版本可以重载(当它们属于同一类时,并且一个作用于常量对象,另一个作用于非常量对象)。

2. 示例

下面是一个简单的函数重载示例,展示了如何根据不同的参数类型来重载print函数。

#include <iostream>
#include <string>

// 第一个 print 函数,用于整数
void print(int i) {
    std::cout << "Printing int: " << i << std::endl;
}

// 第二个 print 函数,用于浮点数
void print(double f) {
    std::cout << "Printing float: " << f << std::endl;
}

// 第三个 print 函数,用于字符串
void print(const std::string& str) {
    std::cout << "Printing string: " << str << std::endl;
}

int main() {
    print(5);         // 调用第一个 print 函数
    print(500.263);   // 调用第二个 print 函数
    print("Hello");   // 调用第三个 print 函数
    return 0;
}

3. 注意事项

  • 当编译器遇到对函数的调用时,它会根据提供的参数来查找匹配的重载函数。如果找不到完全匹配的重载函数,编译器将尝试通过类型转换来寻找合适的重载函数(如果可能的话)。
  • 如果存在多个重载函数都匹配给定的参数,但其中一个函数比其他函数更具体(即,它可以更精确地匹配给定的参数类型,而不需要类型转换),则编译器将选择这个更具体的函数。
  • 如果编译器无法确定哪个重载函数是最佳选择(例如,如果存在两个同样“好”的候选函数),则会报告一个编译时错误,称为“重载解析不明确”。
  • 成员函数重载时,隐式的this指针(指向调用对象的指针)也参与重载解析,但它不直接作为重载的依据。然而,它会影响如何通过成员函数访问其他成员函数或成员变量,这可能间接影响重载解析的结果。
    在这里插入图片描述

四、相关链接

  1. Visual Studio Code下载地址
  2. Sublime Text下载地址
  3. 「C++系列」C++简介、应用领域
  4. 「C++系列」C++ 基本语法
  5. 「C++系列」C++ 数据类型
  6. 「C++系列」C++ 变量类型
  7. 「C++系列」C++ 变量作用域
  8. 「C++系列」C++ 常量知识点-细致讲解
  9. 「C++系列」C++ 修饰符类型
  10. 「C++系列」一篇文章说透【存储类】
  11. 「C++系列」一篇文章讲透【运算符】
  12. 「C++系列」循环
  13. 「C++系列」判断
  14. 「C++系列」函数/内置函数
  15. 「C++系列」数字/随机数
  16. 「C++系列」数组
  17. 「C++系列」字符串
  18. 「C++系列」指针
  19. 「C++系列」引用
  20. 「C++系列」日期/时间
  21. 「C++系列」输入/输出
  22. 「C++系列」数据结构
  23. 「C++系列」vector 容器
  24. 「C++系列」类/对象
  25. 「C++系列」继承

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

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

相关文章

[创业之路-145] :做项目做产品,50米/100米短跑与马拉松长跑,跑法不同,几人的小分队作战与兵团战役,打法不同

目录 一、做项目做产品类同于跑步&#xff0c;50米/100米短跑与马拉松长跑&#xff0c;跑法不同 1. 50米/100米短跑与项目/产品短周期开发的类比 2. 马拉松长跑与长期项目/产品开发的类比 3. 跑法不同的核心差异 二、做项目做产品类同于打仗&#xff0c;几人的小分队作战与…

MySQL-基础篇-事务(事务简介、事务操作、事务的四大特性、并发事务引发的问题、事务的隔离级别)

文章目录 1. 事务简介2. 事务操作2.1 未控制事务2.2 控制事务2.2.1 查看事务的提交方式2.2.2 设置事务的提交方式2.2.3 提交事务2.2.4 回滚事务2.2.5 开启事务2.2.6 完善转账案例 3. 事务的四大特性&#xff08;ACID&#xff09;4. 并发事务引发的问题5. 事务隔离级别5.1 演示5…

Golang | Leetcode Golang题解之第387题字符串中的第一个唯一字符

题目&#xff1a; 题解&#xff1a; type pair struct {ch bytepos int }func firstUniqChar(s string) int {n : len(s)pos : [26]int{}for i : range pos[:] {pos[i] n}q : []pair{}for i : range s {ch : s[i] - aif pos[ch] n {pos[ch] iq append(q, pair{ch, i})} e…

TensorRT模型量化实践

文章目录 量化基本概念量化的方法方式1&#xff1a;trtexec&#xff08;PTQ的一种&#xff09;方式2&#xff1a;PTQ2.1 python onnx转trt2.2 polygraphy工具:应该是对2.1量化过程的封装 方式3&#xff1a;QAT(追求精度时推荐) 使用TensorRT量化实践&#xff08;C版&#xff09…

算法训练营——day2数组部分例题

1 移除元素-力扣27&#xff08;简单&#xff09; 1.1 题目&#xff1a; 移除元素1 1.2 思路及解法 只能覆盖&#xff0c;不能删除 暴力遍历解法 class Solution {public int removeElement(int[] nums, int val) {int sizenums.length;for(int i0;i<size;i){if(nums[i]va…

鸿蒙状态管理

我们开发中构建的页面多为静态页面。如果希望构建一个动态的,有交互的界面,就需要引入‘状态’的概念 用户构建了一个UI模型,其中应用的运行时的状态是参数,当参数改变时,UI作为返回结果,也将进行对应的改变。状态变化带来UI的重新渲染。 自定义组件拥有变量所谓属性,…

数据类型和程序运算

1. 数据类型 1.1 static修饰的变量 本文所有内容在企业考核的笔试题出现频率很高&#xff0c;而且是易错题大家注意下&#xff01; 南友们在玩Java时有没发现&#xff0c;下面这样一个对象&#xff0c;我们即使没有给变量赋值&#xff0c;在创建它后这个变量依旧会有默认值。…

【个人笔记】Git

Tiltle: Github 使用 &#x1f4d6; 快速使用 音标&#xff1a;[ɡɪthʌb] 0 介绍 Github是一个面向开源与私有软件项目的 托管平台&#xff0c;Git源自其内部的版本库格式.2008年上线&#xff0c;18年被微软收购&#xff1b;有很多知名的开源项目&#xff1a;jQuery、pytho…

Android Framework(三)Activity启动流程

文章目录 大纲总体流程 第一阶段&#xff1a;点击图标启动应用流程概览SourceActivity端处理system_service处理启动请求参数的构建activityInfo的解析创建ActivityRecord 窗口层级树的处理获取Task--getOrCreateRootTaskActivityRecord挂载到Task--setNewTask移动Task到容器顶…

最新!yolov10+deepsort的目标跟踪实现

目录 yolov10介绍——实时端到端物体检测 概述 主要功能 型号 性能 方法 一致的双重任务分配&#xff0c;实现无 NMS 培训 效率-精度驱动的整体模型设计 提高效率 精度提升 实验和结果 比较 deepsort介绍&#xff1a; yolov10结合deepsort实现目标跟踪 效果展示…

Elasticsearch的部署和使用

首先对java来说,我们可用的有原生elasticsearch和经过spring二次封装的spring data elasticsearch. 后者自带了一些方法,类似于mybatisplus,可以直接使用,十分方便. 如果是spring项目都建议使用第二种,除非你要深度使用. 首先是服务器的部署.部署之前要知道版本,我在部署时遇到…

GoLang:Go语言开发环境的配置

Go语言 Go语言开发环境的配置 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550263/a…

一款管理苹果设备的软件iMazing3中文破解安装激活教程

iMazing3官方版是一款管理苹果设备的软件&#xff0c;是一款帮助用户管理 IOS 手机的PC端应用程序&#xff0c;能力远超 iTunes 提供的终极 iOS 设备管理器。在iMazing官方版上与苹果设备连接后&#xff0c;可以轻松传输文件&#xff0c;浏览保存信息等&#xff0c;功能比Itune…

NDK编译c/c++文件成so库

目录 背景 Android NDK下载及配置 工程准备 创建Android.mk文件 创建Application.mk文件 编译项目 总结 背景 做算法开发&#xff0c;有时需要将算法编程成so库给其他人调用&#xff0c;很多时候都是在Android平台上使用&#xff0c;这样就会使用到Android NDK进行编译&…

高职院校大数据分析与可视化微服务架构实训室解决方案

一、前言 随着信息技术的飞速发展&#xff0c;大数据已成为推动社会进步与产业升级的关键力量。为了培养适应未来市场需求的高素质技术技能型人才&#xff0c;高职院校纷纷加大对大数据分析与可视化技术的教学投入。唯众&#xff0c;作为国内领先的职业教育解决方案提供商&…

论文速读|大型语言模型作为通用模式机器

项目地址&#xff1a;Large Language Models as General Pattern Machines 本研究探讨了大型语言模型&#xff08;LLMs&#xff09;作为通用模式机器的潜力&#xff0c;特别是在机器人技术领域。研究发现&#xff0c;LLMs 能够在没有额外训练的情况下&#xff0c;通过上下文学…

这才是HR想看到的应届生简历

速创猫今天给大家分享的是应届毕业生简历优化案例&#xff0c;希望对大家求职有帮助。速创猫总结了以下七条简历制作干货&#xff0c;希望对大家有帮助&#xff1a; 简洁明了&#xff1a;简历不是自传&#xff0c;不需要长篇大论。保持每份简历在一页纸内&#xff0c;突出关键…

Linux(CentOS)同步服务器时间之~chrony

Chrony 是一款开源的网络时间协议&#xff08;NTP&#xff09;客户端和服务端软件&#xff0c;旨在提供高精度的时间同步功能。相较于传统的 NTP 实现如 ntpd&#xff0c;Chrony 提供了一些改进和优势&#xff0c;包括更快的同步速度、低延迟、低CPU占用和低内存消耗。以下是 C…

c++ 154 引用

#include<iostream> using namespace std; //引用作为函数参数不需要初始化 void myswap(int *a,int *b) {int c 0;c *a;*a *b;*b c; } void main03() {int a 10;//引用语法 Type & name var;int& b a;b 100;//相当于把a改成100&#xff1b;printf("…

素材无水印素材网站在哪下载?高清的无水印素材资源库分享

找高清无水印素材&#xff1f;蛙学网、Pixabay 等资源库全揭秘&#xff01; 创意十足的你&#xff0c;是不是常为网上素材的烦人水印而头疼&#xff1f;总在寻找高清、干净、无水印的素材资源&#xff0c;却无从下手&#xff1f;别急&#xff0c;今天就为大家推荐几个超实用的…