C++(学习)2024.9.23
目录
运算符重载
1.概念
2.友元函数运算符重载
3.成员函数运算符重载
4.特殊运算符重载
1.赋值运算符重载
2.类型转换运算符重载
5.注意事项
std::string字符串类:
模板与容器
模板
1.函数模板
2.类模板
类内实现
类内声明类外实现
运算符重载
1.概念
C++中可以把部分的运算符开做成函数,此时运算符也可以重载。
运算符预定义的操作只能针对基本数据类型。但是对于自定义类型,也需要类似运算操作,此时就可以重新定义这些运算符的功能,使其支持特定类型,完成特定的操作。
可以被重载的运算符:
算术运算符:+、-、*、/、%、++、--
位操作运算符:&、|、~、^(位异或)、<<(左移)、>>(右移)
逻辑运算符:!、&&、||
比较运算符:<、>、>=、<=、==、!=
赋值运算符:=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=
其他运算符:[]、()、->、,、new、delete、new[]、delete[]不被重载的运算符:
成员运算符"."、指针运算符"*"、三目运算符" ? : "、sizeof、作用域"::"
运算符重载有两种实现方式:
1.友元函数运算符重载
2.成员函数运算符重载
2.友元函数运算符重载
#include <iostream>
using namespace std;class MyInt
{
private:int a;
public:MyInt(int a){this->a=a;}int get_int(){return a;}friend MyInt operator +(MyInt &i,MyInt &i2);friend MyInt operator ++(MyInt &i);//前置++friend MyInt operator ++(MyInt &i,int);//后置++
};
MyInt operator +(MyInt &i,MyInt &i2)
{return i.a+i2.a;
}
MyInt operator ++(MyInt &i)
{return ++i.a;
}MyInt operator ++(MyInt &i,int)
{return i.a++;
}int main()
{MyInt int1(1);MyInt int2(2);MyInt int3=int1+int2;cout<<"int1: "<<int1.get_int()<<endl;cout<<"int2: "<<int2.get_int()<<endl;cout<<"int3=int1+int2"<<endl;cout<<"++int3: "<<(++int3).get_int()<<endl;cout<<"int3++: "<<(int3++).get_int()<<endl;cout<<"int3: "<<int3.get_int()<<endl;return 0;
}
3.成员函数运算符重载
成员函数运算符重载相比于友元函数运算符重载,最主要的区别,在于友元函数的第一个输入参数,在成员函数中使用this指针代替,因此同样的运算符重载,成员函数比友元函数参数少一个。
#include <iostream>
using namespace std;class MyInt
{
private:int a;
public:MyInt(int a){this->a=a;}int get_int(){return a;}MyInt operator +(MyInt &i);MyInt operator ++();//前置++MyInt operator ++(int);//后置++
};
MyInt MyInt::operator +(MyInt &i)
{return this->a+i.a;
}
MyInt MyInt::operator ++()
{return ++this->a;
}MyInt MyInt::operator ++(int)
{return this->a++;
}int main()
{MyInt int1(1);MyInt int2(2);MyInt int3=int1+int2;cout<<"int1: "<<int1.get_int()<<endl;cout<<"int2: "<<int2.get_int()<<endl;cout<<"int3=int1+int2"<<endl;cout<<"++int3: "<<(++int3).get_int()<<endl;cout<<"int3++: "<<(int3++).get_int()<<endl;cout<<"int3: "<<int3.get_int()<<endl;return 0;
}
4.特殊运算符重载
1.赋值运算符重载
除了之前学习的无参构造函数、拷贝构造函数、析构函数以外,如果程序员不手写,编译器还会添加一个赋值运算符重载函数。
赋值运算符重载只能使用成员函数运算符实现。
当类中出现指针类型的成员变量时,默认的赋值运算符重载函数,类似于默认的浅拷贝构造函数,因此需要手动编写解决“浅拷贝”的问题。
#include <iostream>
using namespace std;class MyInt
{int a;
public:MyInt(int a){this->a=a;}int get_int(){return a;}MyInt &operator =(MyInt &i){cout<<"调用赋值运算符重载函数"<<endl;this->a=i.a;return *this;}
};int main()
{MyInt int1(1);MyInt int2(2);cout<<"int1: "<<int1.get_int()<<endl;cout<<"int2: "<<int2.get_int()<<endl;int2=int1;cout<<"int2: "<<int2.get_int()<<endl;return 0;
}
2.类型转换运算符重载
必须使用成员函数运算符重载,且格式比较特殊。
#include <iostream>
using namespace std;class MyInt
{int a;string b="hello";
public:MyInt(int a){this->a=a;}operator int(){return a;}operator string(){return b;}
};int main()
{MyInt int1(1);int a=int1;string b=int1;cout<<"int a = "<<a<<endl;cout<<"string b = "<<b<<endl;return 0;
}
5.注意事项
1.重载的运算符限制在C++语言中已有的运算符范围,不能创建新的运算符。
2.运算符重载本质上也是函数重载,但是不支持函数默认值设定。
3.重载之后运算符不能改变运算符的优先级和结合性,也不能改变运算符的操作数和语法结构。
4.运算符重载必须基于或包含自定义类型,即不能改变基本数据类的运算规则。
5.重载的功能应该与原有的功能相似,避免没有目的的滥用运算符重载。
6.一般情况下,双目运算符建议使用友元函数运算符重载,单目运算符建议使用成员函数运算符重载。
std::string字符串类:
字符串对象是一种特殊类型的容器,专门设计用于操作字符串。
#include <iostream>
#include <string.h>
using namespace std;int main()
{string s;// 判断是否为空cout<<s.empty()<<endl; //1string s1="hello";//隐式调用构造函数cout<<s1<<endl; //hellostring s2("world");//显式调用构造函数cout<<s2<<endl; //world//==、!=、> 、< 判断cout<<(s1==s2)<<endl; //0cout<<(s1!=s2)<<endl; //1cout<<(s1>s2)<<endl; //0cout<<(s1<s2)<<endl; //1string s3(s2);//拷贝构造函数cout<<s3<<endl; //world// 参数1:char * 源字符串// 参数2:保留的字符串数string s4("ABCDE",3);cout<<s4<<endl; //ABC// 参数1:std::string 源字符串// 参数2:不保留的字符数,从头开始string s5(s2,3);cout<<s5<<endl; //ld// 参数1:字符数量// 参数2:字符内容 charstring s6(5,'a');cout<<s6<<endl; //aaaaacout << "原s5 = " << s5 << " " << "原s6 = " << s6 << endl;swap(s5,s6); // 交换cout << "交换后s5 = " << s5 << " " << "交换后s6 = " << s6 << endl;string s7=s1+s2;//字符串连接cout<<s7<<endl; //helloworlds7.append("你好世界");// 向后追加字符串cout<<s7<<endl; //helloworld你好世界s7.push_back('a');// 向后追加单个字符cout<<s7<<endl; //helloworld你好世界a// 插入// 参数1:插入的位置// 参数2:插入的内容s7.insert(0,"123");cout<<s7<<endl; //123helloworld你好世界a// 删除字符串// 参数1:起始位置// 参数2:删除的字符数量s7.erase(2,5);cout<<s7<<endl; //12oworld你好世界a// 替换// 参数1:起始位置// 参数2:被替换的字符数// 参数3:替换的新内容s7.replace(0,3,"++++");cout<<s7<<endl; //++++world你好世界as7.clear(); // 清空cout<<s7.length()<<endl; //0string s8="heiheihei";cout<<s8<<endl; //heiheiheis8="ABCDEFG"; // 重新赋值cout<<s8<<endl; //ABCDEFG// 参数1:拷贝的目标// 参数2:拷贝的字符数量// 参数3:拷贝的起始位置// C++的string到C语言数组char a[20]={0};s8.copy(a,3,0);cout<<a<<endl; //ABC// C++ string 到 c string 用到了C语言中的strcpy// c_str C++的字符串转成C语言的字符数组// c_str 返回一个 const char *char b[20]={0};strcpy(b,s8.c_str());cout<<b<<endl; //ABCDEFGreturn 0;
}
模板与容器
模板
模板可以让类或者函数支持一种通用类型,这种通用类型在实际运行的过程中可以使用任何数据类型,因此可以写一些与类型无关的代码,这种编程方式也被称为“泛型编程”。
通常有两种形式:
1.函数模板
2.类模板
1.函数模板
使一个函数支持模板编程,可以使函数支持通用数据类型。
#include <iostream>
using namespace std;
template<typename T> // typename也可以是class
T add(T a,T b)
{return a + b;
}int main()
{string str1 = "hello";string str2 = "world";cout << add(str1,str1) << endl;return 0;
}
2.类模板
使一个类支持模板编程,可以使一个类支持通用数据类型。
类内实现
#include <iostream>
using namespace std;template<class T>
class Test
{
private:T val;
public:Test(T v){val = v;}T get_val()const{return val;}void set_val(const T &val){this->val = val;}
};int main()
{Test<int> t1(20);cout << t1.get_val() << endl;t1.set_val(10);cout << t1.get_val() << endl;t1.set_val(10.32);cout << t1.get_val() << endl; // 数据窄化10Test<double> t2(2.56);cout << t2.get_val() << endl;t2.set_val(23.12);cout << t2.get_val() << endl;return 0;
}
类内声明类外实现
#include <iostream>
using namespace std;template<class T>
class Test
{
private:T val;
public:Test(T v);T get_val()const;void set_val(const T &val);
};template<class T>
Test<T>::Test(T v)
{val = v;
}template<class T>
T Test<T>::get_val()const
{return val;
}template<class T>
void Test<T>::set_val(const T &val)
{this->val = val;
}int main()
{Test<int> t1(20);cout << t1.get_val() << endl;t1.set_val(10);cout << t1.get_val() << endl;t1.set_val(10.32);cout << t1.get_val() << endl; // 数据窄化10Test<double> t2(2.56);cout << t2.get_val() << endl;t2.set_val(23.12);cout << t2.get_val() << endl;return 0;
}
相关文章:

C++(学习)2024.9.23
目录 运算符重载 1.概念 2.友元函数运算符重载 3.成员函数运算符重载 4.特殊运算符重载 1.赋值运算符重载 2.类型转换运算符重载 5.注意事项 std::string字符串类: 模板与容器 模板 1.函数模板 2.类模板 类内实现 类内声明类外实现 运算符重载 1.概念…...

大数据处理从零开始————3.Hadoop伪分布式和分布式搭建
1.伪分布式搭建(不会用,了解就好不需要搭建) 这里接上一节。 1.1 伪分布式集群概述 伪分布式集群就是只有⼀个服务器节点的分布式集群。在这种模式中,我们也是只需要⼀台机器。 但与本地模式不同,伪分布式采⽤了分布式…...

跟着问题学12——GRU详解
1 GRU 1. 什么是GRU GRU(Gate Recurrent Unit)是循环神经网络(Recurrent Neural Network, RNN)的一种。和LSTM(Long-Short Term Memory)一样,也是为了解决长期记忆 和反向传播中的梯度等问题…...

内核是如何接收网络包的
1、数据如何从网卡到网络协议栈 1.1内核收包的过程 1、数据帧从外部网络到达网卡 2、网卡把数据帧从自己的缓存DMA(拷贝到)和内核共有的RingBuffer上 3、网卡发出硬中断通知CPU 4、CPU响应硬中断,简单处理后发出软中断 5、k’softirqd线程处理软中断,调…...

计算机毕业设计之:基于微信小程序的电费缴费系统(源码+文档+讲解)
博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…...

【leetcode】环形链表、最长公共前缀
题目:环形链表 解法一:哈希表 创建一个哈希表,遍历链表先判断哈希表中是否含有要放入哈希表中的节点,如果该节点已在哈希表中出现那么说明该链表是环形的;如果链表节点出现nullptr那么就退出循环,该链表是…...

C#开发记录如何建立虚拟串口,进行串口通信,以及通信模板
记录时间;2024年4月 记录如何开启虚拟串口以及进行基础串口通信。 建立虚拟串口 使用的软件是vspd,建立虚拟串口之后就可以将他们当成实际物理连接的两个串口进行通信。 之后使用我们之前给出的通信模板,建立一个稍微规矩一点的界面。 界面建立 其中…...

电源设计的艺术:从底层逻辑到工程实践
在电子工程的世界里,电源设计是核心中的核心。它不仅是电子设备的能量源泉,更是整个系统稳定运行的基石。随着科技的不断进步,电源设计的要求也越来越高,从效率、稳定性到体积、成本,每一个维度都是工程师们不断追求的…...

软媒市场新探索:软文媒体自助发布,开启自助发稿新篇章
在繁华喧嚣的软媒市场中,每一个声音都在竭力呼喊,每一个品牌都在奋力展现。而软文,作为一种温柔而坚韧的营销力量,正逐渐崭露头角。特别是软文媒体自助发布平台的出现,更是为企业提供了一个全新的、高效的自助发稿渠道。 软媒市场自助发布平台,正如其名,是一个让企业能够自主发…...
【Kubernetes】常见面试题汇总(二十七)
目录 77.假设公司希望在不同的云基础架构上运行各种工作负载,从裸机到公共云。公司将如何在不同界面的存在下实现这一目标? 78.什么是 Google 容器引擎? 特别说明: 题目 1-68 属于【Kubernetes】的常规概念题。 题目 69-1…...

基于单片机巡迹避障智能小车系统
文章目录 前言资料获取设计介绍设计程序具体实现截图设计获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们…...

Python163邮箱发送:提升发送效率的技巧?
python163邮箱发送邮件教程?python怎么使用163邮箱? Python163邮箱发送作为一种自动化邮件发送方式,越来越受到开发者和企业的青睐。AokSend将探讨如何通过多种技巧提升Python163邮箱发送的效率,从而更好地满足用户需求。 Pytho…...

springboot中的异步任务
在springboot项目中可以通过EnableAsyncAsync的方式简化异步操作,下文使用springboot:3.2.1 源码分析 若一个bean中的公共方法上标注了Async,在系统启动时,会给这个类创建一个代理对象,并将该代理对象作为bean注册到spring容器中 …...

Linux学习笔记8 理解Ubuntu网络管理,做自己网络的主人
本文讲解了Ubuntu下网络由什么管理,介绍了临时ip和路由的设置方法,介绍了静态持久化网络配置的方法以及各网络管理软件之间的关系。 来看看Ubuntu网络管理。 序言 原本学习ubuntu网络管理就是为了检查nginx安装过程中使用wget获取压缩包为什么解析不出…...
理解线程的三大特性:原子性、可见性和有序性
在并发编程中,保护线程安全是一个重要课题。要实现线程安全,我们必须理解并掌握三个核心概念:原子性、可见性和有序性。下面将详细介绍这三个特性及其解决方案。 一、原子性 原子性是指一个操作要么全部完成,要么完全不执行。在多…...
英特尔®以太网网络适配器E810-CQDA1 / E810-CQDA2 网卡 规格书 e810 网卡 规格书 Intel100G E810 网卡 白皮书
英特尔以太网800系列网络适配器 英特尔以太网网络适配器E810-CQDA1 / CQDA2 在10到100Gbps的以太网速度下实现高效的工作负载优化性能 关键特性 •单、双端口QSFP28 •应用设备队列(ADQ) •PCI Express (PCIe) 4.0 x16 •动态设备个性化(DDP) •以太网端口配置工具(EPC…...

好用的idea方法分隔符插件
好用的idea方法分隔符插件...
通过 Xshell 无法连接到 Ubuntu
无法通过 Xshell 连接到 Ubuntu 服务器,通常与 SSH 服务、网络连接、主机防火墙设置问题有关。以下是排查并解决这个问题的步骤: 1. 确保 SSH 服务正在运行 在 Ubuntu 上,SSH 服务必须启动才能连接。如果你有虚拟机或物理机的访问权限&…...

Java面试篇基础部分-Synchronized关键字详解
Synchronized关键字用于对Java对象、方法、代码块等提供线程安全操作。Synchronized属于独占式的悲观锁机制,同时也是可重入锁。我们在使用Synchronized关键字的时候,可以保证同一时刻只有一个线程对该对象进行访问;也就是说它在同一个JVM中是线程安全的。 Java中的每个…...

数据结构之线性表——LeetCode:67. 二进制求和,27. 移除元素,26. 删除有序数组中的重复项
67. 二进制求和 题目描述 67. 二进制求和 给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。 运行代码(javaC) class Solution {public String addBinary(String a, String b) {StringBuilder ansnew StringBuilder();int ca0;for(i…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...

排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...