【C++】类与对象(三)—运算符重载|const成员函数|取地址及const取地址操作符重载

在这里插入图片描述

前言
运算符重载,自增自减运算符重载,const成员函数,取地址及const取地址操作符重载


文章目录

  • 一、运算符重载
    • 自增和自减运算符重载
  • 二、const 成员函数
  • 三、取地址及const取地址操作符重载(了解即可)

一、运算符重载

运算符重载允许重新定义类对象的运算符行为。通过运算符重载,你可以使自定义类型的对象与内置类型一样,使用各种运算符进行操作,从而提高代码的可读性和灵活性。

语法:

//函数名:关键字operator后面接需要重载的运算符符号。
//函数原型:返回值类型 operator操作符(参数列表)
ReturnType operator+(参数) {
        // 重载的 + 运算符的实现
        // 返回类型可以是任何合适的类型
    }

运算符重载可以被重载成类的成员函数,也可以被重载成全局函数。重载成员函数形式的赋值运算符在使用时通过成员访问方式调用,而重载全局函数形式的赋值运算符则直接通过函数名调用。
1. 成员函数形式:

class MyClass {
public:
    // 成员函数形式的赋值运算符重载
    MyClass& operator=(const MyClass& other) {
        // 实现赋值操作
        // 返回当前对象的引用
        if (this != &other) {
            // 实现赋值操作,例如深拷贝资源
        }
        return *this;
    }
};

// 调用
MyClass obj1, obj2;
obj1 = obj2;

在成员函数形式中,运算符重载是通过对象的成员访问方式调用的。左侧的对象(obj1)成为调用对象,右侧的对象(obj2)成为参数传递给成员函数。


2. 全局函数形式:
在全局函数的形式下,函数的参数中不会隐含this指针,因此要传两个参数。

class MyClass {
    // MyClass 的声明
};

// 全局函数形式的赋值运算符重载
MyClass& operator=(MyClass& obj1, const MyClass& obj2) {
    // 实现赋值操作
    // 返回第一个对象的引用
    if (&obj1 != &obj2) {
        // 实现赋值操作,例如深拷贝资源
    }
    return obj1;
}

// 调用
MyClass obj1, obj2;
obj1 = obj2;

在全局函数形式中,运算符重载是通过函数名直接调用的。左侧的对象(obj1)成为函数的第一个参数,右侧的对象(obj2)成为函数的第二个参数。


注意:

  • 不能通过连接其他符号来创建新的操作符:比如operator@
  • 重载操作符必须有一个类类型参数
  • 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
  • 作为成员函数重载时,第一个参数为隐藏的this
  • .* :: sizeof ?: . 这5个运算符不能重载。.* 用于访问类成员指针的操作符。

自增和自减运算符重载

前置和后置自增自减运算符的区分是通过参数列表的一个标识符来实现的。具体来说,前置版本没有任何参数,而后置版本有一个额外的(但不使用)int参数。

这里以自增为例:

重载前置自增运算符
    ReturnType operator++(){}

重载后置自增运算符
    ReturnType operator++(int){}

前置和后置自增的实现:

  • 前置自增运算符重载:

    class MyClass {
    private:
        int value;
    public:
        // 重载前置自增运算符
        MyClass& operator++() {
            ++value;
            return *this;
        }
    };
    
  • 后置自增运算符重载:

    class MyClass {
    private:
        int value;
    public:
        // 重载后置自增运算符
        MyClass operator++(int) {
            MyClass temp = *this; // 保存原始值
            ++value;             // 执行自增操作
            return temp;         // 返回原始值
        }
    };
    

注意:

  • 前置自增运算符返回引用,使得可以对同一对象连续进行自增操作。
  • 后置自增运算符通过返回原始值的副本,再执行自增操作,以允许保留原始值。

二、const 成员函数

将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数
隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。

以日期类为例:
我们创建一个对象,同时加const修饰,变成常量对象。

class Date {
private:
	int _year;
	int _month;
	int _day;
public:
	Date(int year, int month, int day){
		_year = year;
		_month = month;
		_day = day;
	}
	
	void Print() {
		cout << _year << "/" << _month << "/" << _day << endl;
	}
};

int main() {
	//d1 被声明为常量对象,不可修改
	const Date d1(2024, 1, 31);
	
	//报错:“void Date::Print(void)”: 不能将“this”指针从“const Date”转换为“Date &”
	//d1.Print(); 
	return 0;
}

当我们调用成员函数Print()时,编译器会报错,这是因为在通过对象调用成员函数时,this指针被隐式传参,d1是只读不可修改,但在Print()又没有办法对this指针进行限制,所以会出现权限放大的情况。权限只可以平移,缩小,但是不能放大。

//Date成员函数
void Print() {
		cout << _year << "/" << _month << "/" << _day << endl;
	}
	
Date d1(2024, 1, 31);
//d1 是可读可修改,在Print()内同样是可读可修改的,这是权限平移
d1.Print();

//---------------------------------------------------------------------

void Print(const int a) {
		cout << _year << "/" << _month << "/" << _day << endl;
	}
	
Date d1(2024, 1, 31);

int a = 5;
//在Print()中a不可被修改,这是权限缩小
d1.Print(a);

所以提出了const成员函数的概念。在函数名后加const实际上限制了this指针。

//在函数名后面加上const
void Print() const {
		cout << _year << "/" << _month << "/" << _day << endl;
	}
//实际上是对this的修饰
void Print(/*const Date* this*/) {
		cout << _year << "/" << _month << "/" << _day << endl;
	}

另外,如果一个类有两个版本的成员函数,一个是const版本,一个是非const版本,它们可以根据需要被const和非const对象调用。这实际上是函数重载


思考这些问题:

  1. const对象可以调用非const成员函数吗?
  2. 非const对象可以调用const成员函数吗?
  3. const成员函数内可以调用其它的非const成员函数吗?
  4. 非const成员函数内可以调用其它的const成员函数吗?

  1. const对象可以调用非const成员函数吗?

    • 不可以。const 对象只能调用 const 成员函数,因为 const 对象的目的是确保对象的状态不被修改。调用非 const 成员函数会导致编译错误。
  2. 非const对象可以调用const成员函数吗?

    • 是的。非 const 对象可以调用 const 成员函数。这是因为 const 成员函数对对象的状态有只读的访问权限,不会修改对象的成员变量。因此,非 const 对象可以安全地调用 const 成员函数。
  3. const成员函数内可以调用其他的非const成员函数吗?

    • 是的。在 const 成员函数内部,可以调用其他非 const 成员函数,只要这些非 const 成员函数不会修改对象的成员变量。这是因为 const 成员函数对对象的状态有限制,但它可以调用其他不会修改状态的函数。
  4. 非const成员函数内可以调用其他的const成员函数吗?

    • 是的。非 const 成员函数内部可以调用 const 成员函数,因为非 const 成员函数对对象的状态没有限制,可以进行读写操作。因此,非 const 成员函数可以调用 const 成员函数,而不会导致问题。

三、取地址及const取地址操作符重载(了解即可)

Date* operator&(){
	return this;
}

const Date* operator&()const{
	return this;
}

取地址及const取地址操作符重载也是默认成员函数,不需要显式提供,编译器可以自己生成。

class Date{
private:
	int _year;
	int _month;
	int _day;
public:
	Date(int year, int month, int day) {
		_year = year;
		_month = month;
		_day = day;
	}

	Date* operator&(){
		return this;
	}

	const Date* operator&()const{
		return this;
	}
};

int main() {
	Date a(2024, 1, 31);
	const Date b(2024, 1, 3);

	cout << &a << endl;
	cout << &b << endl;
	return 0;
}

在这里插入图片描述


在这里插入图片描述
如果你喜欢这篇文章,点赞👍+评论+关注⭐️哦!
欢迎大家提出疑问,以及不同的见解。

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

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

相关文章

P1967 [NOIP2013 提高组] 货车运输

[NOIP2013 提高组] 货车运输 题目背景 NOIP2013 提高组 D1T3 题目描述 A 国有 n n n 座城市&#xff0c;编号从 1 1 1 到 n n n&#xff0c;城市之间有 m m m 条双向道路。每一条道路对车辆都有重量限制&#xff0c;简称限重。 现在有 q q q 辆货车在运输货物&#x…

Unity Meta Quest MR 开发(三):Scene API 配置+实现虚拟与现实之间的碰撞

文章目录 &#x1f4d5;教程说明&#x1f4d5; Scene 配置⭐开启场景理解功能和应用访问空间数据的权限⭐OVRSceneManager⭐制作 Plane Prefab 和 Volume Prefab⭐运行场景⭐添加透视材质 &#x1f4d5;虚拟与现实物体的碰撞&#xff08;弹球 Demo&#xff09;&#x1f4d5;Mes…

【JavaSE篇】——继承

目录 &#x1f393;继承 ✅为什么需要继承 ✅继承概念 ✅继承的语法 ✅父类成员访问 &#x1f6a9;子类中访问父类的成员变量 1. 子类和父类不存在同名成员变量的情况 2. 子类和父类成员变量同名 &#x1f6a9;子类中访问父类的成员方法 1. 成员方法名字不同 2. 成员…

MyBatis常见面试题汇总

说一下MyBatis执行流程&#xff1f; MyBatis是一款优秀的基于Java的持久层框架&#xff0c;它内部封装了JDBC&#xff0c;使开发者只需要关注SQL语句本身&#xff0c;而不需要花费精力去处理加载驱动、创建连接等的过程&#xff0c;MyBatis的执行流程如下&#xff1a; 加载配…

车载测试Vector工具——基于DoIP的ECU/车辆的连接故障排除

车载测试Vector工具——基于DoIP的ECU/车辆的连接故障排除 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和…

计算huggingface模型占用硬盘空间的实战代码

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

景联文科技受邀出席全国信标委生物特征识别分委会二届五次全会

全国信息技术标准化技术委员会生物特征识别分技术委员会&#xff08;SAC/TC28/SC37&#xff0c;以下简称“分委会”&#xff09;二届五次全会于2024年1月30日在北京顺利召开&#xff0c;会议由分委员秘书长王文峰主持。 分委会由国家标准化管理委员会批准成立&#xff0c;主要负…

N 叉树的层序遍历

给定一个 N 叉树&#xff0c;返回其节点值的层序遍历。&#xff08;即从左到右&#xff0c;逐层遍历&#xff09;。 树的序列化输入是用层序遍历&#xff0c;每组子节点都由 null 值分隔&#xff08;参见示例&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [1,null…

配置实例—VLAN间跨三层通信的交换机配置实例

一、组网需求 企业的不同用户拥有相同的业务&#xff0c;且位于不同的网段。现在相同业务的用户所属的VLAN不相同&#xff0c;需要实现不同VLAN中的用户相互通信。 如图1所示&#xff0c;User1和User2中拥有相同的业务&#xff0c;但是属于不同的VLAN且位于不同的网段。现需要…

【笔记】React Native实战练习(仿网易云游戏网页移动端)

/** * 如果系统看一遍RN相关官方文档&#xff0c;可能很快就忘记了。一味看文档也很枯燥无味&#xff0c; * 于是大概看了关键文档后&#xff0c;想着直接开发一个Demo出来&#xff0c;边学边写&#xff0c;对往后工作 * 开发衔接上能够更顺。这期间肯定会遇到各种各样的问题&a…

基于SpringBoot Vue学生成绩管理系统

大家好✌&#xff01;我是Dwzun。很高兴你能来阅读我&#xff0c;我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结&#xff0c;还为大家分享优质的实战项目&#xff0c;本人在Java项目开发领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#x…

分布式事务 笔记

为什么使用分布式事务 分布式环境下一个业务可能会涉及到多个模块之间的调用&#xff0c;为了保证操作的原子性&#xff0c;分布式事务是最好的解决方案。假设会员服务异常&#xff0c;这是已经完成锁库&#xff0c;锁库无法回滚。 本地事务 事务特性&#xff08;ACID&#…

计算机服务器中了DevicData勒索病毒如何解密,DevicData勒索病毒解密流程

网络数据安全一直是企业关心的主要话题&#xff0c;近期&#xff0c;云天数据恢复中心接到很多企业的求助&#xff0c;企业的计算机服务器遭到了DevicData勒索病毒攻击&#xff0c;导致企业计算机服务器瘫痪无法正常工作&#xff0c;严重影响了工作业务开展。经过云天数据恢复中…

debian12 解决 github 访问难的问题

可以在 /etc/hosts 文件中添加几个域名与IP对应关系&#xff0c;从而提高 github.com 的访问速度。 据搜索了解&#xff08;不太确定&#xff09;&#xff0c;可以添加这几个域名&#xff1a;github.com&#xff0c;github.global.ssl.fastly.net&#xff0c;github.global.fa…

计算机组成原理(0)冯诺依曼体系结构

文章目录 定义**主要特点&#xff1a;****缺陷&#xff1a;** 定义 冯诺依曼体系结构&#xff08;Von Neumann architecture&#xff09;&#xff0c;也称为普林斯顿体系结构&#xff08;Princeton architecture&#xff09;&#xff0c;是一种计算机架构理论&#xff0c;由匈…

在centos 7 中 安装 配置 并 远程连接 MySQL5.7

目录 安装MySQL 1.卸载CentOS7系统自带的mariadb 2.安装依赖库 3.上传MySQL并解压 4.安装MySQL 配置MySQL 1.修改登录密码 2.修改字符集 3.配置远程连接 前言&#xff1a; 安装MySQL版本&#xff1a;mysql-5.7.30-1.el7.x86_64.rpm-bundle 文件需求后台私信 以下7条为…

【C语言】数组的应用:扫雷游戏(包含扩展和标记功能)附完整源代码

这个代码还是比较长的&#xff0c;为了增加可读性&#xff0c;我们还是把他的功能分装到了test.c&#xff0c;game.c&#xff0c;game.h里面。 扫雷游戏的规则相信大家来阅读本文之前已经知晓了&#xff0c;如果点到雷就输了&#xff0c;如果不是雷&#xff0c;点到的格子会显…

红队渗透靶机:LORD OF THE ROOT: 1.0.1

目录 信息收集 1、arp 2、nmap 3、knock 4、nikto 目录探测 1、gobuster 2、dirsearch WEB sqlmap 爆库 爆表 爆列 爆字段 hydra爆破 ssh登录 提权 信息收集 内核提权 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, ty…

十年饮冰难凉热血——HTX重塑巴别塔

明天将会是不同的世界&#xff0c;该由不同的人来塑造。 2024年1月18日&#xff0c;HTX DAO正式成立。 作为区块链生态系统中领先的去中心化自治组织&#xff0c;HTX DAO以创新的治理方式&#xff0c;专注于开放金融和去中心化的代币化经济。 HTX DAO是一个富有远见和包容性…

基于springboot企业客户信息反馈平台源码和论文

网络的广泛应用给生活带来了十分的便利。所以把企业客户信息反馈管理与现在网络相结合&#xff0c;利用java技术建设企业客户信息反馈平台&#xff0c;实现企业客户信息反馈的信息化。则对于进一步提高企业客户信息反馈管理发展&#xff0c;丰富企业客户信息反馈管理经验能起到…