C++类基础(十一)
运算符重载(二)
● 对称运算符通常定义为非成员函数以支持首个操作数的类型转换
struct Str
{int val = 0;Str(int input): val(input){}auto operator+(Str x){std::cout << "auto operator+(Str x)\n";return Str(val + x.val);}
};
int main()
{Str x = 3;Str z = x + 4; //通过类Str的构造函数将4转换为Str类型与x相加Str u = 4 + x; //Error: Invalid operands to binary expression ('int' and 'Str')return 0;
}

struct Str
{int val = 0;Str(int input): val(input){}
};
auto operator+(Str input1, Str input2)
{std::cout << "auto operator+(Str input1, Str input2)\n";return Str(input1.val + input2.val);
}
int main()
{Str x = 3;Str y = x + 3; OKreturn 0;
}
struct Str
{Str(int input): val(input){}friend auto operator+(Str, Str);
private:int val = 0;
};
auto operator+(Str input1, Str input2)
{std::cout << "auto operator+(Str input1, Str input2)\n";return Str(input1.val + input2.val);
}
int main()
{Str x = 3;Str y = x + 3;Str z = 3 + y;return 0;
}
● 移位运算符一定要定义为非成员函数,因为其首个操作数类型为流类型
struct Str
{Str(int input): val(input){}friend auto operator+(Str input1, Str input2){return Str(input1.val + input2.val);}friend auto& operator<<(std::ostream& output, Str input) //返回引用,第一个参数类型是std::ostream{output << input.val;return output;}
private:int val = 0;
};
int main()
{Str x = 3;Str y = x + 3;std::cout << x << ' ' << y <<std::endl;return 0;
}

● 赋值运算符也可以接收一般参数
struct Str
{Str(): val(0){}Str(int input): val(input){}Str& operator=(const Str& input) //重载赋值运算符1。重载运算符只接受一个参数,因为缺省参数是*this。{val = input.val;return *this;}Str& operator=(const std::string& input) //重载赋值运算符2{val = static_cast<int>(input.size());return *this;}
//private:int val;
};
int main()
{Str x = 3;//Str y = "12345"; //调用构造函数而非重载赋值运算符Str y;y = "12345"; //调用重载赋值运算符std::cout << y.val << std::endl;return 0;
}

● operator [] 通常返回引用
struct Str
{Str(): val(0){}Str(int input): val(input){}Str& operator=(const Str& input) //重载赋值运算符1,{val = input.val;return *this;}Str& operator=(const std::string& input) //重载赋值运算符2{val = static_cast<int>(input.size());return *this;}//int operator[](int id) //返回“值”,只读,不可执行写操作int& operator[](int id) //#1返回引用,可读可写,但是*this可被修改{return val;}int operator[](int id) const //#2const修饰构成重载返回“值”,可读不可写,即*this不可被修改{return val;}
//private:int val;
};
int main()
{Str x = 3;x = "12345";std::cout << x[0] << '\n'; //读x[0] = 100; //写std::cout << x[0] << '\n';const Str cx = 3;//std::cout << cx[0] << std::endl; //见#1,Error: No viable overloaded operator[] for type 'const Str'std::cout << cx[0] << std::endl; //OK,见#2return 0;
}

● 自增、自减运算符的前缀、后缀重载方法
struct Str
{Str(): val(0){}Str(int input): val(input){}//Str operator++() //返回“值”,Error: cannot increment value of type 'void'Str& operator++() //前缀自增{++val;return *this;}Str operator++(int) //后缀自增,返回“值”{Str tmp(*this); //调用拷贝构造,构造临时对象,编译器不一定能优化,导致性能上的损失++val;return tmp;}
//private:int val;
};
int main()
{Str s;++(++s); //调用前缀自增std::cout << s.val <<std::endl;std::cout << (s++).val << std::endl; //调用后缀自增std::cout << s.val <<std::endl;return 0;
}

● 使用解引用运算符( * )与成员访问运算符( -> )模拟指针行为
– 注意“ .” 运算符不能重载
通过类对象而不是指向类对象的指针调用其成员的,所以不能重载
struct Str
{Str(int* p): ptr(p){}//operator*() //Error: C++ requires a type specifier for all declarationsint& operator*() //返回引用,支持读写操作{return *ptr;}int operator*() const //返回“值”,只读{return *ptr;}
private:int* ptr;
};
int main()
{int x = 100;Str ptr(&x);std::cout << *ptr << std::endl; //读*ptr = 101; //写std::cout << *ptr << std::endl;return 0;
}

– “→” 会递归调用 操作 “→”
struct Str
{Str(int* p): ptr(p){}Str* operator ->() //重载运算符本质上是个函数{return this;}int val = 5;
private:int* ptr;
};
int main()
{int x = 100;Str ptr(&x);std::cout << ptr->val << std::endl; //#1std::cout << (ptr.operator->()->val) << std::endl; //#2 #1与#2等价return 0;
}

struct Str2
{Str2* operator->(){return this;}int blabla = 20;
};struct Str
{Str(int* p): ptr(p){}Str2 operator ->() //类Str中重载->运算符返回Str2类对象{return Str2{};}int val = 5;
private:int* ptr;
};
int main()
{int x = 100;Str ptr(&x);std::cout << ptr->blabla << std::endl; //#1std::cout << (ptr.operator->().operator->()->blabla) << std::endl; //#2 #1与#2等价return 0;
}

int operator->() //Error: member type 'int' is not a pointer
{return blabla;
}int* operator->() //Error: member reference base type 'int' is not a structure or a union
{return &blabla;
}
● 使用函数调用运算符构造可调用对象
struct Str
{Str(int p): val(p){}int operator()(){return val;}int operator()(int x, int y, int z) //参数列表不同,重载{return val + x + y +z;}
private:int val;
};
int main()
{ Str obj(100);std::cout << obj() << std::endl;std::cout << obj(1, 2, 3) << std::endl;return 0;
}

struct Str
{Str(int p): val(p){}int& operator()(){return this->val;}bool operator()(int input) //参数依据实际情况修改,更加灵活,是Lambda表达式的基础{//return val < input;return val++ < input;}
private:int val;
};
int main()
{ Str obj(100);std::cout << obj() << std::endl;std::cout << obj(1) << std::endl;std::cout << obj() << std::endl;std::cout << obj(199) << std::endl;std::cout << obj() << std::endl;return 0;
}

参考
深蓝学院:C++基础与深度解析
相关文章:
C++类基础(十一)
运算符重载(二) ● 对称运算符通常定义为非成员函数以支持首个操作数的类型转换 struct Str {int val 0;Str(int input): val(input){}auto operator(Str x){std::cout << "auto operator(Str x)\n";return Str(val x.val);} }; int …...
Windows安装系列:SVN Server服务
一、下载与安装 1、下载VisualSVN-Server-5.1.1-x64.msi 地址:Download | VisualSVN Server 2、找到最新版本SVN 5.1.1,直接双击它,弹出如下安装界面 3、点击Next 4、勾选我接受, 点击"Next" 5、默认选项,…...
快速傅里叶算法(FFT)快在哪里?
目录 前言 1、DFT算法 2、FFT算法 2.1 分类 2.2 以基2 DIT(时间抽取) FFT 算法为例 2.2.1 一次分解 2.2.2 多次分解 参考 前言 对信号分析的过程中,为了能换一个角度观察问题,很多时候需要把时域信号波形变换到频域进行分…...
利用Markdown写学术论文资料汇总贴
1是最详细的,重点看! Markdown 写作,Pandoc 转换:我的纯文本学术写作流程 2补充一些细节,也可以看看。 用Markdown写作学术论文 3写得和上面差不多,如果上面两篇有什么问题还没解决,可以看看…...
MySQL 高级查询
目录1.左关联2.右关联3.子查询4.联合查询5.分组查询1.左关联 MySQL中的左关联(Left Join)是一种基于共同列的连接操作, 它将左侧表中的所有行与右侧表中匹配的行结合在一起, 如果右侧表中没有匹配的行,则结果集中右侧…...
JavaSE学习day4_01 循环for,while,do...while
1. 循环高级 1.1 无限循环 for、while、do...while都有无限循环的写法。 最为常用的是while格式的。 因为无限循环是不知道循环次数的,所以用while格式的 代码示例: while(true){} 1.2 跳转控制语句(掌握) 跳转控制语句&…...
C/C++中的static关键字
概述在C/C中都有static关键字的使用,可以分别修饰变量和函数,分为静态变量【静态成员】、静态成员函数。2. static用法概况静态变量的作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为0ÿ…...
67 自注意力【动手学深度学习v2】
67 自注意力【动手学深度学习v2】 深度学习学习笔记 学习视频:https://www.bilibili.com/video/BV19o4y1m7mo/?spm_id_fromautoNext&vd_source75dce036dc8244310435eaf03de4e330 给定长为n 的序列,每个xi为长为d的向量,自注意力将xi 既当…...
电子学会2022年12月青少年软件编程(图形化)等级考试试卷(二级)答案解析
青少年软件编程(图形化)等级考试试卷(二级) 一、单选题(共25题,共50分) 1. 一个骰子,从3个不同角度看过去的点数如图所示,请问5的对面是什么点数?( ) …...
关于链表中插入结点的操作……
服了,好久没敲链表了,这都忘了 newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur-…...
【项目精选】百货中心供应链管理系统
点击下载源码 近年来,随着计算机技术的发展,以及信息化时代下企业对效率的需求,计算机技术与通信技术已经被越来越多地应用到各行各业中去。百货中心作为物流产业链中重要的一环,为了应对新兴消费方式的冲击,从供货到销…...
Qt优秀开源项目之十六:SQLite数据库管理系统—SQLiteStudio
首先,感谢CSDN官方认可 SQLiteStudio是一款开源、跨平台(Windows、Linux和MacOS)的SQLite数据库管理系统。 github地址:https://github.com/pawelsalawa/sqlitestudio 官网:https://sqlitestudio.pl/ 特性很多…...
Python __doc__属性:查看文档
在使用 dir() 函数和 __all__ 变量的基础上,虽然我们能知晓指定模块(或包)中所有可用的成员(变量、函数和类),比如:import string print(string.__all__)程序执行结果为:[ascii_lett…...
电子科技大学操作系统期末复习笔记(一):操作系统概述
目录 前言 操作系统概述 操作系统的目标与功能 操作系统的定义 目标 功能 操作系统的历史 单用户系统 简单批处理系统 多道批处理系统 分时系统 个人电脑 → 分布式系统 → 互联网时代 → 移动计算时代 → ...... 实时系统 操作系统的基本特征 并发 共享 虚拟…...
[实践篇]13.20 Qnx进程管理slm学习笔记(三)
【QNX Hypervisor 2.2用户手册】目录(完结) 4.2 模块 我们可以将组件组合成一个模块。模块中的进程可以组成一个子系统,也可以用于建立一组系统状态,例如基本操作和各种更高级别操作。注意,必须命名模块,以便可以在内部引用它们。而且每个模块必须描述成一个元素,形势如…...
冰冰学习笔记:多线程
欢迎各位大佬光临本文章!!! 还请各位大佬提出宝贵的意见,如发现文章错误请联系冰冰,冰冰一定会虚心接受,及时改正。 本系列文章为冰冰学习编程的学习笔记,如果对您也有帮助,还请各位…...
补充一些前端面试题
javascript有哪些库指路>js中的库uniapp和vue有什么区别什么是uniappuni-app(uni,读you ni,是统一的意思)是一个使用Vue.js开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web&#…...
七大设计原则之单一职责原则应用
目录1 单一职责原则介绍2 单一职责原则应用1 单一职责原则介绍 单一职责(Simple Responsibility Pinciple,SRP)是指不要存在多于一个导致类变更的原因。假设我们有一个 Class 负责两个职责,一旦发生需求变更,修改其中…...
[USACO23JAN] Leaders B
题面翻译 题面描述 FJ 有 NNN 头奶牛,每一头奶牛的品种是根西岛 G 或荷斯坦 H 中的一种。 每一头奶牛都有一个名单,第 iii 头奶牛的名单上记录了从第 iii 头奶牛到第 EiE_iEi 头奶牛的所有奶牛。 每一种奶牛都有且仅有一位“领导者”,对…...
C++模板初阶
C模板初阶泛型编程函数模板概念函数模板格式函数模板原理函数模板的实例化模板参数的匹配原则类模板类模板的定义格式类模板的实例化泛型编程 我们前面学习了C的函数重载功能,那么我们如何实现一个通用的交换函数呢,比如:我传入int就是交换intÿ…...
自动驾驶中的点云处理:Voxel-based与Pillar-based方法实战对比(附代码示例)
自动驾驶中的点云处理:Voxel-based与Pillar-based方法实战对比(附代码示例) 在自动驾驶技术快速发展的今天,点云数据处理已成为环境感知系统的核心环节。激光雷达扫描产生的海量三维点云数据,如何被高效、准确地转化为…...
燃油车虎视眈眈,电车涨价的图谋必将落空,油价上涨的利好将消失
近期以来多家电车企业涨价,美国电车涨价尤为明显,最高涨幅2万元,而国产电车涨价3000-1.4万元不等,凸显出电车似乎突然间对市场乐观起来,导致他们信心十足的在于3月份以来的油价上涨,但是这种涨价将迅速导致…...
手把手教你用STM32F405和SD卡,在阿里云物联网平台上实现OTA升级(MQTT协议详解)
STM32F405实战:基于SD卡与阿里云物联网平台的OTA升级全流程解析 当嵌入式设备部署在野外或工业现场时,固件升级往往成为工程师的噩梦。传统方式需要技术人员携带烧录器奔赴现场,不仅效率低下,在设备数量庞大或分布广泛时更是不切实…...
跨平台终端工具cmatrix:打造震撼的数字雨可视化效果
跨平台终端工具cmatrix:打造震撼的数字雨可视化效果 【免费下载链接】cmatrix Terminal based "The Matrix" like implementation 项目地址: https://gitcode.com/gh_mirrors/cm/cmatrix 你是否曾幻想过在自己的终端中重现《黑客帝国》里令人着迷的…...
前端AI新选择:Transformer.js vs TensorFlow.js,你的项目该用哪个?
前端AI新选择:Transformer.js与TensorFlow.js深度技术选型指南 当浏览器逐渐成为新一代计算平台时,前端开发者正面临一个关键抉择:如何在客户端高效部署机器学习能力?我曾为一个医疗咨询项目选择技术方案时,团队在Tran…...
Save Image as Type:终极Chrome图片格式转换指南,三步快速解决网页图片格式不兼容难题
Save Image as Type:终极Chrome图片格式转换指南,三步快速解决网页图片格式不兼容难题 【免费下载链接】Save-Image-as-Type Save Image as Type is an chrome extension which add Save as PNG / JPG / WebP to the context menu of image. 项目地址:…...
Windows 11下保姆级安装Isaac Sim 4.5.0与Isaac Lab避坑全记录(含CUDA 12.8配置)
Windows 11下Isaac Sim 4.5.0与Isaac Lab全流程部署指南(RTX 4090实测版) 对于机器人仿真和AI开发领域的从业者来说,NVIDIA Isaac Sim和Isaac Lab无疑是当前最强大的工具组合之一。然而,当我在自己的RTX 4090显卡上首次尝试部署这…...
泛微E9流程表单转PDF/HTML实战:手把手教你集成档案系统(附完整代码)
泛微E9流程表单转PDF/HTML全流程开发指南:从原理到实战 在企业管理数字化转型的浪潮中,OA系统与档案系统的无缝对接已成为提升组织效能的刚需。作为国内主流的协同办公平台,泛微E9的流程表单承载着企业核心业务流程数据,如何将这些…...
3步打造你的专属阅读系统:开源工具如何重构数字阅读体验
3步打造你的专属阅读系统:开源工具如何重构数字阅读体验 【免费下载链接】legado-Harmony 开源阅读鸿蒙版仓库 项目地址: https://gitcode.com/gh_mirrors/le/legado-Harmony 你是否曾遇到这样的困扰:阅读APP充斥广告弹窗、书源受限无法找到心仪内…...
容盛兴达丨 32 寸医院自助查询终端机嵌入式触摸查询服务一体机
在数字化浪潮席卷各行各业的今天,医疗机构正经历着从传统服务模式向智慧化、人性化转型的关键时期。医院大厅里,患者及家属常常面临信息获取不便、排队时间长、流程不清晰等困扰。如何利用科技手段优化服务流程、提升患者就医体验,成为医院管…...
