【C++】- 类和对象(运算符重载!!const!!详解!!)

类和对象③

  • 介绍运算符重载
  • 赋值运算符重载
  • ++运算符重载
  • const

在这里插入图片描述在学习C语言时,我们首先接触的就是变量,再深入学习,我们可以利用运算符对变量进行操作,当我们使用C++编写程序时,经常会遇到一些需要对特殊的例如自定义数据类型进行特殊操作的情况。为此,C++提供了运算符重载的机制,可以通过重新定义运算符的行为,实现对自定义数据类型的运算进行特殊定义和处理。在本文中,我们将探讨运算符重载的概念、语法以及一些实际应用。

运算符重载是指通过重新定义运算符的行为,使其适用于自定义数据类型。换句话说,我们可以通过重载运算符来定义两个对象之间的操作,使其具有更直观且符合实际需求的行为。

C++中支持对大部分运算符进行重载,包括算术运算符、比较运算符、位运算符(如 &、|、^)等等。通过运算符重载,我们可以扩展这些运算符的用法,使其适用于我们自定义的数据类型

介绍运算符重载

运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

所以运算符重载是通过函数重载的方式来实现的,其中函数名为运算符的符号。运算符重载函数可以是类的成员函数或友元函数。下面是运算符重载函数的一般形式:

返回值类型 operator运算符 (参数列表) {
    // 运算符的实现
}

在这里插入图片描述在运算符重载函数中,参数列表指定了参与运算的操作数。返回值类型通常为该类类型的引用或对象,以支持连续运算。

需要注意的是,不是所有的运算符都可以被重载,.* :: sizeof ?: . 注意以上5个运算符不能重载。而且在重载运算符时,也需要遵循一些规则和约束条件。例如,运算符的优先级和结合性不能改变,某些运算符(如赋值运算符)应该返回左操作数的引用,等等。

赋值运算符重载

赋值运算符是C++中最常用的运算符之一,它用于将一个对象的值赋给另一个对象。在C++中,我们可以通过重载赋值运算符来定义自定义数据类型的赋值操作,使其适用于我们自己定义的数据类型。

我们已经知道了运算符重载的格式,看代码示例:

class MyClass {
public:
    MyClass& operator=(const MyClass& other)
    {
        // 赋值操作的实现
        return *this;
    }
};

在上面的代码中,我们定义了一个MyClass类,并重载了赋值运算符。注意到返回的是一个 指向当前对象的引用即*this),这是为了支持连续赋值操作。在重载函数中,我们接收一个指向另一个MyClass对象的引用,并将其值赋给当前对象。最后返回一个指向当前对象的引用。

赋值运算符(即=)是用于对象之间的赋值操作。它的重载允许我们定义自定义对象之间的赋值行为。在C++中,赋值运算符可以重载为类的成员函数,但不能重载为全局函数。

这是因为赋值运算符需要访问对象的私有成员变量,以便完成赋值操作。而成员函数具有隐含的this指针,可以直接访问对象的成员变量。因此,将赋值运算符重载为成员函数更加自然和方便。

在这里插入图片描述另一方面,全局函数无法直接访问类的私有成员变量。如果将赋值运算符重载为全局函数,那么它将无法直接访问类的私有成员变量,从而无法完成赋值操作。为了能够访问类的私有成员变量,我们需要使用友元函数或者友元类来实现。但是,这样做会破坏封装性,并且增加了复杂性。

综上所述,将赋值运算符重载为类的成员函数更加合理和方便,因为它可以直接访问类的私有成员变量,而全局函数无法直接访问类的私有成员变量。

赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,故赋值运算符重载只能是类的成员函数。

++运算符重载

重载运算符++有两种形式:前置递增和后置递增。

1. 前置++运算符重载:

// 前置递增运算符重载
ClassName& operator++()
{
    // 实现前置递增操作
    // 返回递增后的对象本身
    return *this;
}

在前置递增运算符重载中,操作符函数不需要任何参数。它直接对被操作对象进行递增操作,并返回递增后的对象本身。例如,可以通过以下方式使用前置递增运算符重载:

ClassName obj;
++obj; // 调用前置递增运算符重载函数

2. 后置++运算符重载::

// 后置递增运算符重载
ClassName operator++(int)
{
    // 创建一个副本用于保存递增前的对象状态
    ClassName temp = *this;
    
    // 实现递增操作
    // 更新当前对象的状态
    
    // 返回递增前的对象副本
    return temp;
}

在后置递增运算符重载中,操作符函数需要一个额外的int参数(虽然该参数不会被实际使用)。它首先创建一个副本用于保存递增前的对象状态,然后对当前对象进行递增操作,并返回递增前的对象副本。但是在调用函数时该参数不用传递,编译器自动传递
例如,可以通过以下方式使用后置递增运算符重载:

ClassName obj;
obj++; // 调用后置递增运算符重载函数

可重载的运算符有很多种,本文只以++运算符和赋值运算符为例演示。

运算符重载是一种非常有用的编程技术,可以简化代码、提高可读性和灵活性。通过为自定义类型重载运算符,我们可以让它们具备与内置类型相似的行为,使得代码更加直观和易于理解。然而,在使用运算符重载时,我们应该注意不要滥用,合理使用才能发挥其优势。

const

在运算符重载中,const关键字的使用非常重要。它可以用于修饰运算符重载函数的参数和返回值,以确保其不会修改对象的状态。

一般情况下,const大致有两种用法:

  1. 修饰参数:
    在运算符重载函数中,如果参数是类的成员变量,并且不需要修改其值,可以将参数声明为const引用。这样可以避免不必要的复制操作,并且告诉编译器该函数不会修改参数的值。

例如,在向量类的加法运算符重载函数中,我们可以将参数声明为const引用:

Vector operator+(const Vector& other) const {
    // ...
}

这样做可以避免对other对象进行复制,并且明确表示该函数不会修改other对象的值。

  1. 修饰返回值:
    如果运算符重载函数返回的是一个临时对象,并且不希望其被修改,可以将返回值声明为const。这样可以防止对返回值进行非法的修改操作。用const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。

    在这里插入图片描述
    这样做可以确保返回的临时对象不会被修改。

总之,使用const关键字可以增加代码的可读性和安全性,尤其在运算符重载中更为重要。它可以提醒开发者该函数不会修改对象的状态,并且可以防止对const修饰的参数和返回值进行非法的修改操作。因此,在编写运算符重载函数时,应该根据实际情况合理地使用const关键字。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

制造工厂ERP系统:从数字销售-生产到财务管理,掌握企业数字化十大核心!

在快速发展的数字化时代,企业(尤其是传统生产制造行业)面临着诸多挑战与机遇。无论是客户体验、供应链管理还是内部流程优化,数字化都在发挥着关键作用。为了更好地应对数字化带来的挑战和机遇为了更好地应对市场变化和提高竞争力…

定了!又一电商巨头拥抱鸿蒙生态

鸿蒙生态 未来可期 近日,鸿蒙生态圈又发布一个令人振奋的消息:京东正式适配原生鸿蒙操作系统!这是继支付宝、微信之后,又一家大厂拥抱鸿蒙的重要举措。可以说,拥抱鸿蒙已经成为了大势所趋! ​ 随着大厂纷…

本地静态资源打包出来,本地配置ng访问服务器(uniapp打包成h5后,使用打包资源连接测试环境测试)

1.下载ng https://nginx.org/en/download.html 2.解压下载的压缩包 3.打包h5静态资源 4.将打包出来的资源放入ng -》html文件夹下面 5.进入ng-》conf-》nginx.conf 进行转发配置 6.启动ng服务,点击nginx.exe 7.浏览器直接访问http://localhost:8081/#/&#x…

Linux------进程的fork()详解

目录 前言 一、fork()的使用 二、fork()的返回值 我们为什么要创建子进程? 父进程与子进程的分流 三、fork的一些难理解的问题 1.fork干了什么事情? 2.fork为什么会有两个返回值 3.fork的两个返回值,为什么会给父进程返回子进程pid…

05--多表操作

1、多表操作 现实生活中,(班级)实体与(学生)实体之间肯定是有关系的,那么我们在设计表的时候,就应该体现出(班级)表与(学生)表之间的这种关系&am…

学习视频一些杂乱的东西

文章目录 ref获取dom元素监听深层的某个属性? 可选链操作符 和 ?? 双问号表达式v-slot 语法糖作用域插槽动态插槽 初始化数组骚操作数字滚动 -> gsapstyle妙招新奇的原型链 object.createB站笔记链接JS相关设计模式ajaxsvgvue3scsswebpack内存泄漏 ref获取dom元素 直接给…

Angular系列教程之组件

文章目录 前言组件的基本概念组件与指令的关系在模板中使用组件总结 前言 在Angular中,组件是构建Web应用程序的核心单元。它们允许我们将UI划分为独立且可重用的部分,并通过数据绑定和事件处理等机制来实现交互性。本文将介绍Angular组件的基本概念&am…

如何公网远程访问Axure RP制作的本地web页面【内网穿透】

文章目录 前言1.在AxureRP中生成HTML文件2.配置IIS服务3.添加防火墙安全策略4.使用cpolar内网穿透实现公网访问4.1 登录cpolar web ui管理界面4.2 启动website隧道4.3 获取公网URL地址4.4. 公网远程访问内网web站点4.5 配置固定二级子域名公网访问内网web站点4.5.1创建一条固定…

❤ Uniapp使用三( 打包和发布上线)

❤ Uniapp使用三( 打包和发布上线) 一、介绍 什么是 uniapp? uniapp 是一种基于 Vue.js 的多平台开发框架,它可以同时用于开发安卓、iOS、H5 等多个平台。因此,只需要写一次代码就可以在多个平台上运行,提高了开发效率。 打包…

蓝桥杯 彩灯与任务

题目描述 输入样例 5 5 5 4 3 3 9 R 1 C 4 R 5 A 3 R 2 输出样例 5 3 3 思路 第一眼读不懂旋转是啥意思&#xff0c;根据样例连蒙带猜猜出来&#xff0c;其实就是把整个数组中的挪动几个位置。也很自然的按照题意写出来如下代码&#xff1a; #include <iostream> using…

如果你正在学自动化测试,那么请你仔细看完这篇文章

接触了不少同行&#xff0c;由于他们之前一直做手工测试&#xff0c;现在很迫切希望做自动化测试&#xff0c;其中不乏工作5年以上的人。 本人从事软件自动化测试已经近5年&#xff0c;从server端到web端&#xff0c;从API到mobile&#xff0c;切身体会到自动化带来的好处与痛楚…

kylin集群负载均衡(kylin3,hbaseRIF问题)

hbase历险记 目录 hbase历险记 寻找问题 分析原因 解决方案 方案1&#xff08;资源问题、失败&#xff09; 方案2&#xff08;成功&#xff09; 寻找问题 不知道你是不是有这样的疑惑。我kylin是个单机&#xff0c;我使用的hbase是个集群&#xff0c;但内存全在某一台机…

高并发缓存问题分析以及分布式锁的实现

一,场景概述: 在高并发的环境下,比如淘宝,京东不定时的促销活动,大量的用户访问会导致数据库的性能下降,进而有可能数据库宕机从而不能产生正常的服务,一般一个系统最大的性能瓶颈&#xff0c;就是数据库的io操作,如果发生大量的io那么他的问题也会随之而来。从数据库入手也是…

Python基础知识:整理13 利用pyecharts生成折线图

首先需要安装第三方包pyecharts 1 基础折线图 # 导包&#xff0c;导入Line功能构建折线图对象 from pyecharts.charts import Line # 折线图 from pyecharts.options import TitleOpts # 标题 from pyecharts.options import LegendOpts # 图例 from pyecharts.options im…

CSAPP阅读笔记-程序的机器级表示

程序的机器级表示 计算机执行机器代码&#xff0c;用字节序列编码低级的操作&#xff0c;包括处理数据、管理内存、读写存储设备上的数据&#xff0c;以及利用网络通信。编译器基于编程语言的规则、目标机器的指令集和操作系统遵循的惯例&#xff0c;经过一系列的阶段生成机器…

微信小程序---如何创建分包

1.在项目根目录中&#xff0c;创建分包的根目录&#xff0c;名为subpkg&#xff0c;这个名字可以自己定义 2.在 pages.json 中&#xff0c;和 pages 节点平级的位置声明 subPackages 节点&#xff0c;用来定义分包相关的结构&#xff1a; 3.在分包目录&#xff0c;点击右键新建…

进程切换和是Linux2.6内核中进程调度的算法

正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 进程切换 进程并发就需要做到进程切换&#xff0c;一个CPU一套寄存器但是需要运行的进程有很多…

发票系统对接诺诺平台

诺诺平台判断设备不在线&#xff0c;导致开票失败 代码方面优化&#xff1a;调用接口的时候&#xff1a;是否先调用在线状态检测接口&#xff0c;确认开票设备是在线的状态 &#xff0c;在调用诺诺平台&#xff0c;不在线直接拦截&#xff1b;例如&#xff1a;这个原理就类似于…

DIYgif表情包怎么做?gif表情包制作方法分享

Gif表情包是我们生活交流中必不可少的一种方式&#xff0c;能够表达自己的心情&#xff0c;也能够调节气氛。平时我们的gif表情包都是从网上下载或是别人发送的&#xff0c;那么我们怎么自己DIYgif表情包呢&#xff1f;这时候&#xff0c;用qq表情在线制作&#xff08;https://…