【C++第二阶段】运算符重载-【+】【cout】【++|--】

你好你好!
以下内容仅为当前认识,可能有不足之处,欢迎讨论!


文章目录

  • 运算符重载
    • 加法运算符重载
    • 重载左移运算符
    • 递增|减运算符重载


运算符重载

加法运算符重载

What

普通的加减乘除,只能应付C++中已给定的数据类型的运算,对其重载,使得满足多种多样的运算。

对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。

注意

①对于内置的数据类型表达式的运算符是不可能改变的。

②不要滥用运算符重载。

对于①,基本的运算符运算不改变,int+int = int , float + float = float.

对于②,重写相加,就写相加,名副其实。如果重写了加法运算符,里面却写➖或者×÷,代码可读性会变差。

代码

成员函数重载加法运算符

#include<iostream>
#include<string>
using namespace std;
void test_0208_0();class Person {
public:float person_height;int person_weight;Person operator+(Person& person);//成员函数运算符重载
};Person Person::operator+(Person& person) {Person temp;temp.person_height = this->person_height + person.person_height;temp.person_weight = this->person_weight + person.person_weight;return temp;
}void test_0208_0() {Person per, son , person_sum;per.person_weight = 70;per.person_height = 1.83;son.person_weight = 60;son.person_height = 1.83;person_sum = per + son;//成员函数重载加法运算符相当于://person_sum = per.operator+(son);cout << "person sum 总身高为:" << person_sum.person_height << "." << endl;cout << "person sum 总体重为:" << person_sum.person_weight << "." << endl;}int main() {cout << "hello world !" << endl;test_0208_0();system("pause");return 0;
}

运行结果

image-20240208162939715

可以看到,将两人的身高和体重在加法运算符重载之后进行了求和。

全局函数重载加法运算符

#include<iostream>
#include<string>
using namespace std;
void test_0208_0();
void test_0208_1();
void test_0208_2();class Person {
public:float person_height;int person_weight;Person operator+(Person& person);//成员函数运算符重载
};Person operator+(Person& per, Person& son) {Person temp;temp.person_height = per.person_height + son.person_height;temp.person_weight = per.person_weight + son.person_weight;return temp;
}void test_0208_0() {Person per, son , person_sum;per.person_weight = 70;per.person_height = 1.83;son.person_weight = 60;son.person_height = 1.83;person_sum = per + son;//全局成员函数重载加法运算符相当于://person_sum = operator+(per , son);cout << "person sum 总身高为:" << person_sum.person_height << "." << endl;cout << "person sum 总体重为:" << person_sum.person_weight << "." << endl;}int main() {cout << "hello world !" << endl;test_0208_0();system("pause");return 0;
}

运行结果

image-20240208162939715

重载左移运算符

场景:

想要cout直接输出类里面的各种属性,简单地使用``cout<<person<<endl;会报错。需要重写<<`运算符。

How

考虑到加法运算符的重载,使用成员函数重载左移运算符。

但此时,有两个问题:①函数返回值是什么数据类型?②如何调用?

回答问题①

通过点击cout右键后,选择转到定义。

image-20240208171255369

接着出现:

image-20240208171337955

可以看到,cout属于的类是ostream输出流对象。

所以,如果想链式调用函数,可以将返回值设置为ostream。同时,只能用引用方式传递,因为全局只能有一个。

成员函数重载左移运算符:

#include<iostream>
#include<string>
using namespace std;
void test_0208_1();class Person {
private :int weight;double height;
public:Person(int weight, double height);void operator<<(ostream& cout);
};Person::Person(int weight, double height) {this->weight = weight;this->height = height;
}void Person::operator<<(ostream &cout) {cout << "person 的身高为:" << this->height << "." << endl;cout << "person 的体重为:" << this->weight << "." << endl;}void test_0208_1() {int weight = 70;double height = 1.85;Person person(weight, height);person << cout;//等价于//person.operator<<(cout);
}int main() {cout << "hello world !" << endl;test_0208_1();system("pause");return 0;}

运行结果为:

image-20240208172157591

但是不想要person<<cout;,或者person.operator<<(cout);这样的写作方式,而是要重载后的输出方式cout<<person<<endl;

如果现在加上<<endl;则后面会报错。

image-20240208172334418

image-20240208172322256

这个方式实际上是链式调用函数出错出现的问题,可以更改返回值为对应的ostream &引用来解决。

比如,以上代码中的成员函数改为:

class Person {private :int weight;double height;
public:Person(int weight, double height);//返回值由void 改为ostream &ostream& operator<<(ostream& cout);
};Person::Person(int weight, double height) {this->weight = weight;this->height = height;
}//返回值由void 改为ostream
ostream& Person::operator<<(ostream &cout) {cout << "person 的身高为:" << this->height << "." << endl;cout << "person 的体重为:" << this->weight << "." << endl;return cout;
}void test_0208_1() {int weight = 70;double height = 1.85;Person person(weight, height);person << cout<<endl;//添加endl后不会报错//等价于//person.operator<<(cout);
}

运行结果为

image-20240208172548485

但仍没有解决想要使用cout<<person<<endl;进行输出的问题。

原因在于,如果用成员函数重载,则person只能出现在左侧,cout出现在右侧。所以,更换为使用全局函数。

全局函数重载左移运算符

#include<iostream>
#include<string>
using namespace std;
void test_0208_0();
void test_0208_1();
void test_0208_2();class Person {//要注意添加全局函数为类的友元,否则私有成员属性无法访问。friend ostream& operator<<(ostream& out, Person &person);
private :int weight;double height;
public:Person(int weight, double height);//void operator<<(ostream& cout);
};Person::Person(int weight, double height) {this->weight = weight;this->height = height;
}ostream& operator<<(ostream& out,Person& person) {//这里的out是引用,就是别名。out << "person 的身高为:" << person.height << "." << endl;out << "person 的身高为:" << person.weight << "." << endl;return out;
}void test_0208_1() {int weight = 70;double height = 1.85;Person person(weight, height);cout << person << endl;//全局函数重载等价于//operator<<(cout, person);
}int main() {cout << "hello world !" << endl;test_0208_1();system("pause");return 0;
}

operator<<(cout,person)运行结果:

image-20240208174206491

递增|减运算符重载

目的

想要达到一个自定义的整数类实现前置递增或后置递增的操作。

How

分为前置递增运算符和后置递增运算符。

对于前置递增运算符,返回值需要是MyInt类型的,因为cout已经重写,所以最好是这种类型。

返回值是指针,因为是对于当前的类进行的加减操作。

对于后置递增运算符,需要在参数中写入占位符,编译器明白这是后置运算符。

#include<iostream>
#include<string>
using namespace std;
void test_0208_1();
void test_0208_2();
void test_0208_3();
void test_0208_4();
void test_0208_5();class MyInt {friend ostream& operator<<(ostream& print, MyInt my_int);private:int num;public:MyInt() {num = 0;}MyInt(int number) {num = number;}//成员函数-前置递增函数//返回值为什么是数字,因为想要它实现前置递增的功能,让cout输出,但是cout不知道怎么输出void类型的变量//所以需要返回值//需要返回自身,this是指针,解引用之后才是自身。//至于返回值,则是一个引用//MyInt& operater++() {//this->num++;//return *this;//}//若返回值,则以下为返回值的测试案例MyInt& operator++() {this->num++;return *this;}//成员函数-后置递增函数MyInt& operator++(int) {static MyInt temp = *this;this->num++;return temp;}MyInt& operator--() {--this->num;return *this;}MyInt& operator--(int) {static MyInt temp = *this;this->num--;return temp;}};ostream& operator<<(ostream& print, MyInt my_int) {cout << my_int.num;return print;
}void test_0208_2() {cout << "==========test_0208_2()==========" << endl;MyInt my_int(20);cout <<"my_int \t==>" << my_int << endl;cout << "========\t" << endl;cout << "++my_int ==>" << ++my_int << endl;cout << "my_int \t==>" << my_int << endl;//使用返回值的前置递增函数,两次递增后,新的值为新的随机值,而不是my_int//对于my_int为什么是11,是因为只有第一个作为存储值留下来了cout << "========\t" << endl;cout << "++(++my_int)==>" << ++(++my_int) << endl;cout <<"my_int \t==>" << my_int << endl;cout << "==========test_0208_2()==========\n" << endl;}void test_0208_3() {cout << "==========test_0208_3()==========" << endl;MyInt my_int = 30;cout << "原始的my_int = " << my_int << "." << endl;cout << "my_int ++ 后,my_int = " << my_int++ << "." << endl;cout << "现在的my_int = " << my_int << "." << endl;cout << "==========test_0208_3()==========\n" << endl;
}void test_0208_4() {cout << "==========test_0208_4()==========" << endl;MyInt my_int(40);cout << "my_int \t==>" << my_int << endl;cout << "========\t" << endl;cout << "--my_int ==>" << --my_int << endl;cout << "my_int \t==>" << my_int << endl;//使用返回值的前置递增函数,两次递增后,新的值为新的随机值,而不是my_int//对于my_int为什么是11,是因为只有第一个作为存储值留下来了cout << "========\t" << endl;cout << "--(--my_int)==>" << --(--my_int) << endl;cout << "my_int \t==>" << my_int << endl;cout << "==========test_0208_4()==========\n" << endl;}void test_0208_5() {cout << "==========test_0208_5()==========" << endl;MyInt my_int = 50;cout << "原始的my_int = " << my_int << "." << endl;cout << "my_int -- 后,my_int = " << my_int-- << "." << endl;cout << "现在的my_int = " << my_int << "." << endl;cout << "==========test_0208_5()==========\n" << endl;
}int main() {cout << "hello world !" << endl;test_0208_5();test_0208_4();test_0208_3();test_0208_2();system("pause");return 0;
}

运行结果

image-20240209010008149


以上是我的学习笔记,希望对你有所帮助!
如有不当之处欢迎指出!谢谢!

学吧,学无止境,太深了

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

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

相关文章

Java SE多态

文章目录 1.多态&#xff1a;1.1.什么是多态&#xff1a;1.2.多态实现条件&#xff1a;1.2.1.重写&#xff1a;1.2.2.向上转型&#xff1a; 1.多态&#xff1a; 1.1.什么是多态&#xff1a; 多态的概念&#xff1a;通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是去…

分享76个表单按钮JS特效,总有一款适合您

分享76个表单按钮JS特效&#xff0c;总有一款适合您 76个表单按钮JS特效下载链接&#xff1a;https://pan.baidu.com/s/1CW9aoh23UIwj9zdJGNVb5w?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集…

【开源】JAVA+Vue+SpringBoot实现实验室耗材管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 耗材档案模块2.2 耗材入库模块2.3 耗材出库模块2.4 耗材申请模块2.5 耗材审核模块 三、系统展示四、核心代码4.1 查询耗材品类4.2 查询资产出库清单4.3 资产出库4.4 查询入库单4.5 资产入库 五、免责说明 一、摘要 1.1…

echarts 曲线图自定义提示框

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>曲线图</title><!-- 引入 ECharts 库 -->…

【知识整理】招人理念、组织结构、招聘

1、个人思考 几个方面&#xff1a; 新人&#xff1a;选、育、用、留 老人&#xff1a;如何甄别&#xff1f; 团队怎么演进&#xff1f; 有没有什么注意事项 怎么做招聘&#xff1f; 2、 他人考虑 重点&#xff1a; 1、从零开始&#xff0c;讲一个搭建团队的流程 2、标…

Mybatis开发辅助神器p6spy

Mybatis什么都好&#xff0c;就是不能打印完整的SQL语句&#xff0c;虽然可以根据数据来判断一二&#xff0c;但始终不能直观的看到实际语句。这对我们想用完整语句去数据库里执行&#xff0c;带来了不便。 怎么说呢不管用其他什么方式来实现完整语句&#xff0c;都始终不是Myb…

2万字曝光:华尔街疯狂抢购比特币背后

作者/来源&#xff1a;Mark Goodwin and whitney Webb BitcoinMagazine 编译&#xff1a;秦晋 全文&#xff1a;19000余字 在最近比特币ETF获得批准之后&#xff0c;贝莱德的拉里-芬克透露&#xff0c;很快所有东西都将被「ETF化」与代币化&#xff0c;不仅威胁到现有的资产和商…

InternLM大模型实战-3.InternLM+Langchain搭建知识库

文章目录 前言笔记正文大模型开发范式RAGFinetune LangChain简介构建向量数据库搭建知识库助手1 InternLMLangchain2 构建检索问答链3 优化建议 Web Demo 部署搭建知识库 前言 本文是对于InternLM全链路开源体系系列课程的学习笔记。【基于 InternLM 和 LangChain 搭建你的知识…

今年春节联欢晚会中的扑克魔术到底是咋变的?

今年的刘谦给全国观众带来了俩魔术&#xff0c;一个是洗牌一个是撕牌&#xff0c;前面第一个魔术看不出来太神奇了&#xff0c;但是第二魔术感觉挺有趣的我可以简单分析分析。 然后我们列出这个魔术的关键步骤&#xff1a; 打乱四张牌 1 2 3 4 对折、撕开、面向同一个方向重…

Windows下搭建Redis Sentinel

下载安装程序 下载Redis关于Windows安装程序&#xff0c;下载地址 下载成功后进行解压&#xff0c;解压如下&#xff1a; 配置redis和sentinel 首先复制三份redis.windows.conf&#xff0c;分别命名为&#xff1a;redis.6379.conf、redis.6380.conf、redis.6381.conf&…

无心剑中译佚名《春回大地》

The Coming of Spring 春回大地 I am coming, little maiden, With the pleasant sunshine laden, With the honey for the bee, With the blossom for the tree. 我来啦&#xff0c;小姑娘 满载着欣悦的阳光 蜂儿有蜜酿 树儿有花绽放 Every little stream is bright, All …

机器学习:分类决策树(Python)

一、各种熵的计算 entropy_utils.py import numpy as np # 数值计算 import math # 标量数据的计算class EntropyUtils:"""决策树中各种熵的计算&#xff0c;包括信息熵、信息增益、信息增益率、基尼指数。统一要求&#xff1a;按照信息增益最大、信息增益率…

iOS AlDente 1.0自动防过充, 拯救电池健康度

经常玩iOS的朋友可能遇到过长时间过充导致的电池鼓包及健康度下降问题。MacOS上同样会出现该问题&#xff0c;笔者用了4年的MBP上周刚拿去修了&#xff0c;就是因为长期不拔电源的充电&#xff0c;开始还是电量一半的时候不接电源会黑屏无法开机&#xff0c;最后连着电源都无法…

春晚刘谦魔术的模拟程序

昨晚春晚上刘谦的两个魔术表演都非常精彩&#xff0c;尤其是第二个魔术&#xff0c;他演绎了经典的约瑟夫环问题&#xff01; 什么是约瑟夫环问题&#xff1f; 约瑟夫环&#xff08;Josephus problem&#xff09;是一个经典的数学问题&#xff0c;最早由古罗马历史学家弗拉维…

VUE学习——数组变化侦测

官方文档 变更方法&#xff1a; 使用之后&#xff0c;ui可以直接发生改变。改变原数组 替换数组&#xff1a; 使用之后需要接受重新赋值&#xff0c;不然ui不发生改变。不改变原数组

JavaScript表单元素

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 表单作为页面的重要交互组件,JavaScript 提供了丰富的表单元素操作方…

计算机网络第6章(应用层)

6.1、应用层概述 我们在浏览器的地址中输入某个网站的域名后&#xff0c;就可以访问该网站的内容&#xff0c;这个就是万维网WWW应用&#xff0c;其相关的应用层协议为超文本传送协议HTTP 用户在浏览器地址栏中输入的是“见名知意”的域名&#xff0c;而TCP/IP的网际层使用IP地…

Flink-CDC实时读Postgresql数据

前言 CDC,Change Data Capture,变更数据获取的简称,使用CDC我们可以从数据库中获取已提交的更改并将这些更改发送到下游,供下游使用。这些变更可以包括INSERT,DELETE,UPDATE等。 用户可以在如下的场景使用cdc: 实时数据同步:比如将Postgresql库中的数据同步到我们的数仓中…

每日五道java面试题之java基础篇(一)

第一题 什么是java? PS&#xff1a;碎怂 Java&#xff0c;有啥好介绍的。哦&#xff0c;⾯试啊。 Java 是⼀⻔⾯向对象的编程语⾔&#xff0c;不仅吸收了 C语⾔的各种优点&#xff0c;还摒弃了 C⾥难以理解的多继承、指针等概念&#xff0c;因此 Java 语⾔具有功能强⼤和简单易…

微信小程序checkbox多选

效果图 <view class"block"><view class"header"><view class"header-left"><text class"pu-title">数据</text><text class"pu-tip">至少选择一个指标</text></view>&l…