简单的C++:【运算符重载】新手易学

news2024/11/27 8:31:25

学过C语言的同志们应该都知道位运算符>> 和 << (右移左移),但是这两个运算符在C++中还是我们的输入和输出流操作符,那么这是为什么呢?,了解完本篇文章之后,我们再来回答这个问题。

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其 返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似

函数名字为:关键字operator后面接需要重载的运算符符号。

函数原型:返回值类型 operator操作符(参数列表)

但是

不能通过连接其他符号来创建新的操作符:比如operator@

重载操作符必须有一个类类型参数 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义

作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐 藏的this

.*  ::  sizeof   ?:   .   注意以上5个运算符不能重载

假设我们定义了如下的一个学生类,包含的有学生的年龄,学号,和名字。

#include <iostearm>
#include <string.h>
using namespace std;

class Student
{
public:
	Student(int age, int id, const char* name)
	{
		_age = age;
		_id = id;
		_name = new char[strlen(name) + 1];
		//const传给非const的类型是不被允许的,通过开辟新的空间拷贝的方式去实现_name
		strcpy(_name, name);
	}

	~Student()
	{
		_age = _id = 0;
		delete[] _name;
		_name = nullptr;
	}

	void print()
	{
		cout << _age << " " << _id << " " << _name << endl;
	}
private:
	int _age;
	int _id;
	char* _name;
};

int main()
{
	Student s1(18, 12345, "zhangsan");
	s1.print();

	return 0;
}

对于自定义类型我们是不能直接使用标准输出cout打印信息的,如下所示:

必须再写一个专门的打印函数。(如果成员变量是public,那么也可以通过直接访问内部成员变量的方式去打印)。

调用该函数去实现相应的功能:

 那么如果我们现在就是想要通过cout<<s1来实现打印功能该怎么办呢?

接下来轮到operator(运算符重载关键字)登场了。

我们首先要注意两个重点,一是运算符,而是重载。

operator只能操作之前(语言定义的)存在过的运算符,为该运算符重新赋予新的功能,这种将运算符旧功能通过operator编写的函数,重新为它赋予新的功能就叫做重载。

现在我们接着来谈怎么实现我们的cout<<s1;

如果我们将该函数实现在类的内部,*this就会抢占第一个位置,也就是cout,但是cout实际是ostream类型的并不是Student类型,所以我们将其定义在全局。

接下来我们来一点点的解释,然后再优化一下该函数的缺点。

首先 <<左边的cout会自动的匹配到函数的第一个形参,<<右边的s1会匹配到第二个形参上去(cout << s1)。其实我们也可以将cout和s1分别看成operator<<函数的第一个实参和第二个实参。

为了减少拷贝的次数,所以使用了引用而不是简单的传值。

cout的类型是ostream的

在该函数内部的时候,out是cout的别名,out就相当于cout,我们直接使用即可,但是该类的成员变量都是private类型的,我们不能直接在类的外部进行访问,此时将我们的函数,设置为该类的友元函数即可。

 友元函数:可以访问类的内部

或者在类的内部实现三个函数,分别读取对应的三个成员变量(比较的挫不建议)

上面我们实现<<的重载的返回类型是void的,为了和我们标准的cout实现的相同,即cout<<1<<2<<endl;一次打印多个,我们将返回类型改为ostream。

完整的代码如下:

#include<iostream>
#include <string.h>

using namespace std;

class Student
{
	friend void operator<<(ostream& out, const Student& s);
public:
	Student(int age, int id, const char* name)
	{
		_age = age;
		_id = id;
		_name = new char[strlen(name) + 1];
		//const传给非const的类型是不被允许的,通过开辟新的空间拷贝的方式去实现_name
		strcpy(_name, name);
	}

	~Student()
	{
		_age = _id = 0;
		delete[] _name;
		_name = nullptr;
	}

	void print()
	{
		cout << _age << " " << _id << " " << _name << endl;
	}
private:
	int _age;
	int _id;
	char* _name;
};


ostream& operator<<(ostream& out, const Student& s)
{
	out << s._age << " " << s._id << " " << s._name << endl;
}

int main()
{
	Student s1(18, 12345, "zhangsan");
	s1.print();

	cout << s1;
	return 0;
}

运行结果:

运算符重载的用处很大,特别是对于我们的自定义类型,比如日期类的加减法,我们是无法直接对自定义的日期类使用+-的,但是可以使用运算符重载去实现日期类的+-。

我们知道,C++是兼容C的,那么C++的<<就是一个运算符的重载,当然<<在C++中也是可以作为为运算符使用的,如下:

3的二进制右移1位就是0001(十进制1) 。

在C++中会自动识别<<和>>对应的操作数的类型来决定是位运算还是运算符重载<<  >>。

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

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

相关文章

python和C++代码实现模拟动态指针时钟

一、python代码实现及turtle库简单介绍 桌面时钟项目描述 1、使用turtle库绘制时钟外形及表针&#xff1b; 2、使用datetime获取系统时间&#xff1b; 3、时钟动态显示 turtle库基本命令 1、turtle.setup()函数&#xff1a;用于启动一个图形窗口&#xff0c;它有四个参数…

2023-02-22干活小计

复现BERT&#xff1a; 只能说爷今天干了一上午一下午的代码 bert的输入&#xff1a; batch_size * max_len * emb_num 768 * 768 bert的输出&#xff1a;三维字符级别特征(NER可能就更适合) 二维篇章级别特征(比如文本分类可能就更适合) batch_size * max_len * emb_num, ba…

亲身试验 Outlook防关联方法分享

Outlook在海外的用途是很广泛的&#xff0c;不仅可以用于收发邮件&#xff0c;还可以作为各类第三方网站的登录凭证。所以Microsoft对于Outlook的监管还是比较严格的&#xff0c;跨境卖家大量注册Outlook账号使用的话很容易被检测出关联然后被封号。龙哥针对Outlook防关联的问题…

35-Golang中的方法

Golang中的方法方法的介绍和使用方法的声明和调用方法的调用和传参机制原理方法的声明(定义)方法注意事项和细节讨论方法和函数的区别方法的介绍和使用 在某些情况下&#xff0c;我们需要声明(定义)方法。比如person结构体&#xff0c;除了有一些字段外(年龄&#xff0c;姓名……

unix高级编程-僵尸进程和孤儿进程

僵尸进程&#xff1a; 一个父进程利用fork创建子进程&#xff0c;如果子进程退出&#xff0c;而父进程没有利用wait 或者 waitpid 来获取子进程的状态信息&#xff0c;那么子进程的状态描述符依然保存在系统中。 孤儿进程&#xff1a;一个父进程退出&#xff0c; 而它的一个或…

java+Selenium+TestNg搭建自动化测试架构(3)实现POM(page+Object+modal)

1.Page Object是Selenium自动化测试项目开发实践的最佳设计模式之一&#xff0c;通过对界面元素的封装减少冗余代码&#xff0c;同时在后期维护中&#xff0c;若元素定位发生变化&#xff0c;只需要调整页面元素封装的代码&#xff0c;提高测试用例的可维护性。 PageObject设计…

软件测试,刚进入一个公司如何快速上手一个项目?

目录 前言 客观现状 主观能动性 总结感谢每一个认真阅读我文章的人&#xff01;&#xff01;&#xff01; 重点&#xff1a;配套学习资料和视频教学 前言 刚入职一家新公司&#xff0c;做的项目是之前很少接触的行业&#xff0c;该怎么快速的熟悉并上手自己的工作&#xf…

富文本编辑组件封装,tinymce、tinymce-vue

依赖&#xff1a;package.json yarn add tinymce tinymce/tinymce-vue {"dependencies": {"tinymce/tinymce-vue": "5.0.0","tinymce": "6.3.1","vue": "3.2.45",}, } 本地依赖&#xff1a; 在publ…

JIT-即时编译技术

VM&#xff08;HotSpot&#xff09;执行引擎中包含解释器与JIT编译器热点代码&#xff08;执行多次&#xff09;才有JIT编译的必要&#xff08;JIT编译阈值&#xff09;JVM&#xff08;HotSpot&#xff09;会有两个计数器&#xff08;次数/回边&#xff09;判断方法/代码块是否…

缺少IT人员的服装行业该如何进行数字化转型?

服装行业上、下游产业链长&#xff0c;产品属性复杂&#xff0c;是劳动密集型和技术密集型紧密结合的产物&#xff0c;是典型的实体经济代表。 近二十年是服装业发展的机遇和挑战之年&#xff0c;从“世界工厂”“中国制造”&#xff0c;逐渐向“中国设计”转变,中国服装产业经…

Kotlin新手教程九(协程)

一、协程 协程从Kotlin1.3开始引入&#xff0c;本质上协程就是轻量级的线程。协程的基本功能点有&#xff1a; 轻量&#xff1a;可以在单个线程上运行多个协程&#xff0c;因为协程支持挂起&#xff0c;不会使正在运行协程的线程阻塞。挂起比阻塞节省内存&#xff0c;且支持多…

扬帆优配|雷达供应商Arbe暴涨近50%;A股毫米波雷达概念异军突起

今日早盘&#xff0c;A股全体低开高走&#xff0c;上证指数围绕3300点重复抢夺&#xff0c;两市成交呈现大幅萎缩的趋势&#xff0c;显示市场谨慎情绪较为浓厚。 盘面上&#xff0c;白酒、国防军工、新能源、医药等板块涨幅居前&#xff0c;电信运营、网络游戏、稳妥、房地产等…

Sqoop导出hive/hdfs数据到mysql中---大数据之Apache Sqoop工作笔记006

然后我们看看数据利用sqoop,从hdfs hbase中导出到mysql中去 看看命令可以看到上面这个 这里上面还是mysql的部分,然后看看 下面--num-mappers 这个是指定mapper数 然后下面这个export-dir这里是,指定hdfs中导出数据的目录 比如这里指定的是hive的一个表/user/hive/warehouse…

IOS开发中遇到的问题总结【持续更新】

目录 知识点补给站 1. SwiftUI中的Image控件使用系统图标 知识点补给站 【Swift学习】关于 Swift | Swift 编程语言中文教程&#xff08;The Swift Programming Language&#xff09;【SwiftUI学习】不要惊慌! SwiftUI Example【SwiftUI学习】https://goswiftui.com【AppIcon…

C#、JAVA读写PLC物联网Modbus

Modbus协议是一种常用于工业自动化领域的通信协议&#xff0c;它使用简单、易实现、可靠的特点得到了广泛应用。物联网中的设备也需要使用Modbus协议进行通信。本文将介绍物联网Modbus通信的相关内容。一、Modbus协议简介Modbus协议是一种串行通信协议&#xff0c;它最初由Modi…

浅谈ThreadLocal的原理

文章目录1.ThreadLocal初识2.ThreadLocal底层原理3.ThreadLocal核心API3.1.get()方法3.2.set()方法3.3.remove()方法3.4.核心代码及流程4.ThreadLocalMap5.Hash冲突怎么解决6.ThreadLocal内存泄漏问题及解决办法7.应用场景8.总结1.ThreadLocal初识 ThreadLocal概念&#xff1a…

RPC(2)------ Netty(NIO) + 多种序列化协议 + JDK动态代理实现

依赖包解释 Guava 包含了若干被Google的 Java项目广泛依赖 的核心库&#xff0c;例如&#xff1a;集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、并发库 [concurrency libraries] 、通用注解 [common annotations] 、字符串处理 [string process…

Windows部署Jar包的三种方式

文章目录1、cmd命令启动2、bat脚本启动2.1 启动jar包2.2 关闭服务3、使用WinSW3.1 重命名3.2 xml配置3.3 安装服务3.4 卸载服务3.5 启动和停止服务1、cmd命令启动 这种方式比较简单&#xff0c;但是窗口关闭后服务也就被杀死了&#xff0c;命令如下 java -jar xxx.jar2、bat脚…

nignx(安装,正反代理,安装tomcat设置反向代理,ip透传)

1安装nginx 安装wget Yum install -y wget 下载(链接从官网找到右键获取) 以下过程root 安装gcc Yum -y install gcc c 安装pcre Yum install -y pcre pcre-devel Openssl Yum install -y openssl openssl-devel 安装zlib Yum install -y zlib zlib-devel 安装make Yum inst…

纯手动搭建hadoop集群记录001_搭建虚拟机_调通网络_配置静态IP_安装JDK---大数据之Hadoop3.x工作笔记0162

1.首先准备机器,172.19.126.115 172.19.126.116 172.19.126.117 我准备了3台 Windows机器 2.然后我打算在Windows机器上使用虚拟机,搭建3台Centos虚拟机来进行安装hadoop 3.这里我们的3台windows机器中的,3台linux虚拟机也使用了3个IP,分别是 172.19.126.120 172.19.126.1…