【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://www.hqwc.cn/news/462019.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot 笔记 003 Bean注册

使用Idea导入第三方jar包这种方法是不对的 使用maven命令导入jar包 官网下载maven Maven – Download Apache Maven 解压缩后在命令行输入命令&#xff0c;注意看输出的结果&#xff0c;安装的是不是你本地的maven仓库 mvn install:install-file -Dfile"D:\common-pojo-2…

【NICN】探索牛客之求阶乘

1.题目描述 递归和非递归分别实现求n的阶乘&#xff08;不考虑溢出的问题&#xff09; 2.代码解题 2.1递归 递归思想&#xff1a; Fac(N) 1*2*3*……*N递归方式实现&#xff1a;1 N < 1 Fac(N)Fac(N-1)*N N > 2 long long Fac(int N) {if(N < 1)return 1;retu…

放飞梦想,扬帆起航——1888粉丝福利总结

目录 1.祝福 2.准备 3.抽奖 4.制作 5.添加 6.成果 7.感谢 8.福利 9.祝福 1.祝福 马上就是除夕了&#xff0c;在这里提前预祝大家春节快乐&#xff0c;小芒果在这里给大家拜年了&#xff01; 2.准备 其实很早之前我就在幻想着哪一天我的粉丝量能突破1888&#xff0c;…

OCP使用CLI创建和构建应用

文章目录 环境登录创建project赋予查看权限部署第一个image创建route检查pod扩展应用 部署一个Python应用连接数据库创建secret加载数据并显示国家公园地图 清理参考 环境 RHEL 9.3Red Hat OpenShift Local 2.32 登录 通过 crc console --credentials 可以查看登录信息&…

云游戏发行需要哪些条件

云游戏是一种创新性的游戏服务模式&#xff0c;将游戏运算和渲染等处理任务移至云端服务器&#xff0c;通过互联网实时传输画面和操作指令&#xff0c;使玩家能够在低端终端设备上也能流畅玩游戏。要做云游戏发行&#xff0c;需要考虑一系列条件&#xff0c;包括技术、基础设施…

猫头虎分享已解决Bug :内存泄漏(Memory Leak)

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

Go语言的100个错误使用场景(30-40)|数据类型与字符串使用

前言 大家好&#xff0c;这里是白泽。 《Go语言的100个错误以及如何避免》 是最近朋友推荐我阅读的书籍&#xff0c;我初步浏览之后&#xff0c;大为惊喜。就像这书中第一章的标题说到的&#xff1a;“Go: Simple to learn but hard to master”&#xff0c;整本书通过分析100…

小白都能看懂的力扣算法详解——链表(二)

LC 24.两两交换链表中的节点 题目描述&#xff1a;给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 24. 两两交换链表中的节点 -…

TCP 传输控制协议——详细

目录 1 TCP 1.1 TCP 最主要的特点 1.2 TCP 的连接 TCP 连接&#xff0c;IP 地址&#xff0c;套接字 1.3 可靠传输的工作原理 1.3.1 停止等待协议 &#xff08;1&#xff09;无差错情况 &#xff08;2&#xff09;出现差错 &#xff08;3&#xff09;确认丢失和确认迟到…

SECS/GEM300需要实现哪些内容

GEM300实现设备全自动化&#xff0c;也是金南瓜已经全面支持功能&#xff0c;作为国内首家和最好的300mm标准软件。 GEM300包含E4、E5、E30、E37、E39、E40、E84、E87、E90、E94、E116等 CJob全称Conrtol Job 1. 控制设备作业的控制 2. 包括队列、开始、暂停、继续、完成等等…

Mac使用AccessClient打开Linux堡垒机跳转闪退问题解决

登录公司的服务器需要使用到堡垒机&#xff0c;但是mac使用AccessClient登录会出现问题 最基础的AccessClient配置 AccessClient启动需要设置目录权限&#xff0c;可以直接设置为 权限 777 chmod 777 /Applications/AccessClient.app注: 如果不是这个路径,可以打开终端,将访达中…

探索设计模式的魅力:代理模式揭秘-软件世界的“幕后黑手”

设计模式专栏&#xff1a;http://t.csdnimg.cn/U54zu 目录 引言 一、魔法世界 1.1 定义与核心思想 1.2 静态代理 1.3 动态代理 1.4 虚拟代理 1.5 代理模式结构图 1.6 实例展示如何工作&#xff08;场景案例&#xff09; 不使用模式实现 有何问题 使用模式重构示例 二、…