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ÿ…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
