C++零碎记录(八)
14. 运算符重载简介
14.1 运算符重载简介
① 运算符重载:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
② 对于内置的数据类型的表达式的运算符是不可能改变的。
14.2 加号运算符重载
① 加号运算符作用:实现两个自定义数据类型相加的运算。
#include <iostream>
using namespace std;//加号运算符重载
class Person
{
public://1、成员函数重载+号Person operator+(Person& p){Person temp;temp.m_A = this->m_A + p.m_A;temp.m_B = this->m_B + p.m_B;return temp;}int m_A;int m_B;
};/*
//全局函数重载+号
Person operator+(Person &p1, Person &p2)
{Person temp;temp.m_A = p1.m_A + p2.m_A;temp.m_B = p1.m_B + p2.m_B;return temp;
}
*///函数重载的版本
Person operator+(Person& p1, int num)
{Person temp;temp.m_A = p1.m_A + num;temp.m_B = p1.m_B + num;return temp;
}void test01()
{Person p1;p1.m_A = 10;p1.m_B = 10;Person p2;p2.m_A = 10;p2.m_B = 10;//成员函数重载本质调用 //Person p3 = p1.operator+(p2);//全局函数重载本质调用 //Person p3 = operator+(p1,p2);Person p3 = p1 + p2; //重载本质被简化后的形式//运算符重载,也可以发生函数重载Person p4 = p1 + 10; //Person + intcout << "p3.m_A:" << p3.m_A << endl;cout << "p3.m_B:" << p3.m_B << endl;cout << "p4.m_A:" << p4.m_A << endl;cout << "p4.m_B:" << p4.m_B << endl;}int main()
{test01();system("pause");return 0;}
运行结果:
- p3.m_A:20
- p3.m_B:20
- p4.m_A:20
- p4.m_B:20
- 请按任意键继续. . .
14.3 左移运算符重载
① 左移运算符重载:可以输出自定义数据类型。
② 重载左移运算符配合友元可以实现自定义数据类型。
#include <iostream>
using namespace std;//左移运算符
class Person
{friend ostream& operator<<(ostream& out, Person& p); public:Person(int a, int b){m_A = a;m_B = b;}/*//利用成员函数重载 左移运算符 p.operator<<(cout) 简化版本 p << cout//成员函数不能利用重载<<运算符,因为无法实现cout在左侧//当不知道返回值是什么类型的时候,可以先写个void,以后再改void operator<<(Person& p){}*/private:int m_A;int m_B;
};//只能利用全局函数重载左移运算符
//如果返回类型为void,那么就无法无限追加,也没有办法在后面添加换行符
ostream & operator<<(ostream &cout, Person &p) //本质 operator << (cout , p) , 简化 cout << p//cout是别名,这里可以取out、kn...//cout为ostream输出流数据类型
{cout << "m_A= " << p.m_A << " m_B=" << p.m_B;return cout;
}void test01()
{Person p(10,10);cout << p << " hello world" << endl;
}int main()
{test01();system("pause");return 0;}
运行结果:
- m_A= 10 m_B=10 hello world
- 请按任意键继续. . .
14.4 递增运算符
① 递增运算符重载:通过重载递增运算符,实现自己的整型数据。
② 前置递增返回的是引用,后置递增返回的是值。
#include <iostream>
using namespace std;//重载递增运算符class MyInteger
{friend ostream& operator<<(ostream& cout, MyInteger myint);public:MyInteger(){m_Num = 0;}//重载前置++运算符,返回引用是为了一直对一个数据进行递增操作,而返回值并不是一直对一个数据进行递增操作 MyInteger& operator++(){//先进行++运算m_Num++;//再将自身做一个返回return *this; //把自身做一个返回}//重载后置++运算符 int代表占位参数,可以用于区分前置和后置递增//后置递增不能返回引用,因为temp是局部变量,如果返回temp,当程序运行完后变量就释放了,再调用temp就是非法操作了 MyInteger operator++(int){//先记录当时结果MyInteger temp = *this;//后 递增m_Num++;//最后将记录结果做返回return temp;}
private:int m_Num;
};//只能利用全局函数重载左移运算符
ostream & operator<<(ostream &cout, MyInteger myint) //本质 operator << (cout , p) , 简化 cout << p//cout是别名,这里可以取out、kn...//cout为ostream输出流数据类型
{cout << myint.m_Num;return cout;
}void test01()
{MyInteger myint;cout << ++(++myint) << endl;cout << myint << endl;
}void test02()
{MyInteger myint;cout << myint++ << endl;cout << myint << endl;}int main()
{test01();test02();/*int a = 0;cout << ++(++a) << endl; //运行结果为2cout << a << endl; //运行结果为2,表示一直对一个数据进行递增*/system("pause");return 0;}
运行结果:
- 2
- 2
- 0
- 1
- 请按任意键继续. . .
14.5 赋值运算符
① C++编译器至少给一个类添加4个函数:
1. 默认构造函数(无参,函数体为空)
2. 默认析构函数(无参,函数体为空)
3. 默认拷贝构造函数,对属性进行值拷贝
4. 赋值运算符operator=,对属性进行值拷贝
5. 如果类中有属性指向堆区,做赋值操作时也会出现浅拷贝问题。
#include <iostream>
using namespace std;//重载赋值运算符class Person
{
public:Person(int age){m_Age = new int(age);}~Person(){if (m_Age != NULL){delete m_Age;m_Age = NULL;}}//重载 赋值运算符//如果返回的是值,而不是引用,是创建一个拷贝函数,返回的是一个副本,而不是自身Person& operator=(Person& p){//编译器默认是提供浅拷贝//m_Age = p.m_Age;//浅拷贝带来的问题是,当创建数据在堆区时,析构代码导致内存重复释放,报错//应该先判断是否有属性在堆区,如果有先释放干净,然后再深拷贝if (m_Age != NULL){delete m_Age;m_Age = NULL;}//深拷贝m_Age = new int(*p.m_Age);//返回对象本身return *this;}int *m_Age;
};void test01()
{Person p1(18);Person p2(20);Person p3(23);p3 = p2 = p1; //赋值操作cout << "p1的年龄为:" << *p1.m_Age << endl;cout << "p2的年龄为:" << *p2.m_Age << endl;cout << "p3的年龄为:" << *p3.m_Age << endl;}int main()
{test01();/*int a = 10;int b = 20;int c = 30;c = b = a;cout << "a= " << a << endl;cout << "b= " << b << endl;cout << "c= " << c << endl;*/system("pause");return 0;}
运行结果:
- p1的年龄为:18
- p2的年龄为:18
- p3的年龄为:18
- 请按任意键继续. . .
14.6 关系重载运算符
#include <iostream>
using namespace std;
#include<string>//重载关系运算符class Person
{
public:Person(string name, int age){m_Name = name;m_Age = age;}//重载 == 号bool operator==(Person& p){if (this->m_Name == p.m_Name && this->m_Age == p.m_Age){return true;}return false;}bool operator!=(Person& p){if (this->m_Name != p.m_Name && this->m_Age != p.m_Age){return true;}return false;}string m_Name;int m_Age;
};void test01()
{Person p1("Tom", 17);Person p2("Jerry", 18);if (p1 == p2){cout << "p1和p2是相等的!" << endl;}else{cout << "p1和p2是不相等的!" << endl;}if (p1 != p2){cout << "p1和p2是不相等的!" << endl;}else{cout << "p1和p2是相等的!" << endl;}}int main()
{test01();system("pause");return 0;}
运行结果:
- p1和p2是不相等的!
- p1和p2是不相等的!
- 请按任意键继续. . .
14.7 函数调用运算符重载
① 函数调用运算符()也可以重载。
② 由于重载后使用的方式非常像函数的调用,因此称为仿函数。
③ 仿函数没有固定写法,非常灵活。
#include <iostream>
using namespace std;
#include<string>//函数调用运算符重载//打印输出类
class MyPrint
{
public://重载函数调用运算符void operator()(string test){cout << test << endl;}};//正常函数
void MyPrint02(string test)
{cout << test << endl;
}void test01()
{MyPrint myPrint;myPrint("hello world");}//仿函数非常灵活,没有固定的写法
//加法类
class MyAdd
{
public:int operator()(int num1, int num2){return num1 + num2;}
};void test02()
{MyAdd myadd;int ret = myadd(100,100);cout << "ret = " << ret << endl;//匿名函数对象cout << MyAdd()(100, 100) << endl;// MyAdd()为创建一个匿名对象,匿名对象的特点为当前行执行完立即释放
}int main()
{test01();MyPrint02("hello world"); //由于使用起来非常类似于函数调用,因此称为仿函数test02();system("pause");return 0;}
运行结果:
- hello world
- hello world
- ret = 200
- 200
- 请按任意键继续. . .
链接:https://www.zhihu.com/question/437657370/answer/1692846096
相关文章:
C++零碎记录(八)
14. 运算符重载简介 14.1 运算符重载简介 ① 运算符重载:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。 ② 对于内置的数据类型的表达式的运算符是不可能改变的。 14.2 加号运算符重载 ① 加号运算符作用&#x…...
基于matlab的扩频解扩误码率完整程序分享
clc; clear; close all; warning off; addpath(genpath(pwd)); r5; N2^r-1;%周期31 aones(1,r); mzeros(1,N); for i1:(2^r-1) temp mod((a(5)a(2)),2); for jr:-1:2 a(j)a(j-1); end a(1)temp; m(i)a(r); end mm*2-1;%双极性码 %产生随…...
算法:轮转数组---循环取模运算
1、题目: 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 2、分析特点: 轮转 > 取模运算 我们可以使用额外的数组来将每个元素放至正确的位置。用 n 表示数组的长度,我们遍历原数组&a…...
Vue教程
官网vue快速上手 vue示例图 请点击下面工程名称,跳转到代码的仓库页面,将工程 下载下来 Demo Code 里有详细的注释 代码:LearnVue...
算法之双指针题型:
双指针例题小总结: 力扣27: 移除元素 力扣题目链接 双指针分为: 快慢双指针:同一个起点,同向出发 相向双指针:从两端出发,方向相反,终会相遇 经典的双指针(快慢双指…...
vue传递给后端时间格式问题
前端处理 首先前端使用moment.js进行处理 data.userEnrolDate moment(data.userEnrolDate).format(YYYY-MM-DD HH:mm:ss);后端处理 JsonFormat(timezone "GMT8", pattern "yyyy-MM-dd HH:mm:ss") DateTimeFormat(pattern "yyyy-MM-dd HH:mm:ss…...
php使用jwt作登录验证
1 在项目根目录下,安装jwt composer require firebase/php-jwt 2 在登录控制器中加入生成token的代码 use Firebase\JWT\JWT; use Firebase\JWT\Key; class Login extends Cross {/*** 显示资源列表** return \think\Response*/public function index(Request $r…...
【zlm】 PTS DTS
在音视频编码和传输中,PTS(Presentation Time Stamp)和DTS(Decoding Time Stamp)是两个关键的时间戳,用于确保音视频帧的顺序和同步。它们在多媒体处理中扮演重要的角色: PTS(Presen…...
【两周学会FPGA】从0到1学习紫光同创FPGA开发|盘古PGL22G开发板学习之DDR3 IP简单读写测试(六)
本原创教程由深圳市小眼睛科技有限公司创作,版权归本公司所有,如需转载,需授权并注明出处 适用于板卡型号: 紫光同创PGL22G开发平台(盘古22K) 一:盘古22K开发板(紫光同创PGL22G开发…...
第6章 内核模块符号导出实验(iTOP-RK3568开发板驱动开发指南 )
在上一小节中,给大家讲解了驱动模块传参实验,使用insmod命令加载驱动时可以进行参数的传递,但是每一个内核模块之间是相互独立的,那模块间的符号传递要怎样进行呢,让我们带着疑问来进行本章节的学习吧! 6.…...
Android12.0首次开机默认授予app运行时权限(去掉运行时授权弹窗)第二种方法
1.概述 在12.0的系统产品开发中,在6.0以后对于权限的申请,都需要动态申请,所以会在系统首次启动后,在app的首次运行时,会弹出授权窗口,会让用户手动授予app运行时权限,在由于系统产品开发需要要求默认授予app运行时权限,不需要用户默认授予运行时弹窗,所以需要在首次开…...
conda和Python的虚拟环境如何结合使用,以及二者之间到底有什么区别?
问题描述 今天在复现streamlit的代码时(参考Streamlit 讲解专栏(一):安装以及初步应用),根据这篇博文指导,要先用以下指令创建一个虚拟环境: # 创建虚拟环境(使用venv&a…...
宇凡微YE09合封芯片,集成高性能32位mcu和2.4G芯片
合封芯片是指将主控芯片和外部器件合并封装的芯片,能大幅降低开发成本、采购成本、减少pcb面积等等。宇凡微YE09合封芯片,将技术领域推向新的高度。这款高度创新性的芯片融合了32位MCU和2.4G芯片,为各种应用场景提供卓越的功能和性能。 32位M…...
使用perf_analyzer和model-analyzer测试tritonserver的模型性能超详细完整版
导读 当我们在使用tritonserver部署模型之后,通常需要测试一下模型的服务QPS的能力,也就是1s我们的模型能处理多少的请求,也被称为吞吐量。 测试tritonserver模型服务的QPS通常有两种方法,一种是使用perf_analyzer 来测试&#…...
docker 部署springboot(成功、截图)
1.新建sringboot工程并打包 2.编写Dockerfile文件 # 基础镜像使用java FROM openjdk:8 # 作者 MAINTAINER feng # VOLUME 指定了临时文件目录为/tmp。 # 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp VOLUME /tmp # 将jar包添加…...
VMware ubuntu空间越用越大
前言 用Ubuntu 1604编译了RK3399的SDK,之后删了一些多余的文件,df - h 已用21G,但window硬盘上还总用了185GB,采用了碎片整理,压缩无法解决 1 启动Ubuntu后, 安装 VMware Tools(T) 、 2 打开ubuntu终端,压…...
stm32 学习笔记:GPIO输出
一、GPIO简介 引脚电平 0-3.3V,部分可容忍5V,对输出而言最大只能输出3.3V, 只要可以用高低电平来控制的地方,都可以用GPIO来完成,如果控制的功率比较大的设备,只需加入驱动电路即可 GPIO 通用输入输出口,可配置为 8种 …...
css换行
强制显示一行,超出... .box{white-space: nowrap; /* 强制显示一行 */overflow: hidden;text-overflow: ellipsis; /* 超出... */ } 自动换行 一般默认制动换行 .box1{word-wrap:break-word; } 显示2行,超出... .box2 {overflow: hidden;display: -…...
面试算法-常用数据结构
文章目录 数据结构数组链表 栈队列双端队列树 1)算法和数据结构 2)判断候选人的标准 算法能力能够准确辨别一个程序员的功底是否扎实 数据结构 数组 链表 优点: 1)O(1)时间删除或者添加 灵活分配内存空间 缺点: 2&…...
【动态规划刷题 10】等差数列划分 最长湍流子数组
413. 等差数列划分 链接: 413. 等差数列划分 如果一个数列 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。 例如,[1,3,5,7,9]、[7,7,7,7] 和 [3,-1,-5,-9] 都是等差数列。 给你一个整数数组 nums ,返回…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
