5. 操作符重载与临时对象
1. 操作符重载之一:把操作符重载成成员函数
在C++里面,操作符是一种函数,这是C++的一大特点。
操作符重载的原因:
- 因为函数库中没有两个复数直接相加的函数,只有实数和实数相加的函数,如1.2+2.3=3.5。
对于成员函数:+=
- c2调用了+=,c2就是this,或者说this此时就指向了c2(this是一个指针).
2. return by reference的故事(传递者无需知道接收端是以by reference还是by value的形式接收object,如果是前者,就收的就是object的地址)
3. 返回值是写void还是写一个具体类型的故事
如果使用者只是这样调用+=这个重载函数:c2+=c1,那么返回类型complex&写成void是没有问题的。但如果这样调用:c3+=c2+=c1,返回void类型的话,就有问题了。
4. 在class body(类区域)外面定义函数
5. 操作符重载(操作符是非成员函数的情况,无隐含参数this(指针))
为了应付客户的3种可能用法,需要在类体外写3个对应的处理加法的函数
- (1)复数+复数 c1+c2
- (2)实数+复数 5+c1
- (3)复数+实数 c1+7
5. 临时对象(temp object)的故事
下面这些函数绝对不可以return by reference, 因为,它们返回的必定是个local object.
一定要return by value.
typename();(类名后面+小括号),这是一个特殊语法,是创建临时对象的特殊语法。如下面函数体中的complex()就是在创建临时对象,临时对象的生命周期就是这创建的那一行,到下一行生命就结束了。
再比如:
6. 单目运算符+,-的重载(正号操作,取反操作)
第一个正号操作,返回的是原来的东西,没有产生新的东西(新的local object,而下面代码中取反的操作产生了新的东西),那完全可以retrun by reference啊,这个是标准库里面的东西,那么厉害的人会注意不到这一点吗?有可能。这里其实可以retrun by reference。complex后面可以加个&
网友1:因为参数是const complex& x(const 型变量引用),如果返回值是引用的话,相当于去掉了const. 所以还是应该return by value. 实验了一下,果然是这样,retrun by reference(即写成inline complex&)的话,生成解决方案的时候会出错:错误C2440“return”: 无法从“const complex”转换为“complex &”
网友2:因为传入的参数是const类型的引用,如果将返回值改成引用,相当于将const类型转换为非const类型,这在编译上是通不过的。
7. 双目操作符“==”的重载
3种情况:
- 判断一个复数是否等于另一个复数
- 判断一个实数是否等于另一个复数
-
判断一个复数是否等于另一个实数
写一个函数一般考量两个点,这两点影响着程序执行的效率:
- 参数传递要不要by reference?
- 返回值传递要不要by reference?
8. 双目操作符“!=”的重载
9. 共轭复数
9. 重载输出操作符“<<”进行复数或者共轭复数的输出
可以说的有以下几点:
- 参数传递,均是pass by reference;
- 返回值传递,return by reference;
- 如果不是连续输出,函数的返回值类型可以设计成void,如果使用连续输出,函数的返回值类型不能是void类型;
- “<<”是双目运算符,需要提供2个参数;
- 运算符永远是作用在左边的对象上,没有作用在右边上的;
- “<<”左边的“cout”是一个对象,这个对象的类别是:ostream,标准库中有这样一句:
就像对象c1的类别是complex,对象7的类别是int,对象7.9的类别是double一样; - cout<<c1; 这一句会返回一个ostream类型的对象(的引用);
- 返回类型前不可以加"const",因为连续输出的时候被丢到屏幕上的东西一直在变,即每有一个新的输出变量“os”的状态就会发生变化(由于这个原因,ostream& os的前面不可以加const修饰符),相当于一个变量的值一直在发生变化;
- 这段代码是标准库中提供的例子。
- <<不可以写成成员函数,因为返回值是ostream类型的对象,这个类(ostream类)是标准库中定义好的,所以只能写成全局函数,不能写成局部函数。
注解:
- 函数体重多个<<相当于连续调用<<函数。
- 如果<<的返回值类型是void,则无法连续调用,必须返回ostream类型的对象,才可以被继续调用。
- return os <<'('<< real(x) << ',' << imag(x) << ')'; 这一句其实很奇妙,因为:os <<'(' 相当于是调用了<<函数,调用后的返回值是ostream这种类型的对象,这种对象作为参数继续被<<调用,继续输出x的实部(real())到屏幕上,然后再次返回一个ostream这种类型的对象,继续作为参数被<<调用,输出','到屏幕上,循环往复下去,直到输出所有你想输出到屏幕上的东西。
- 变量尽量写在private区,因为变量不想被外界看到。
- 函数尽量写在public区,因为函数主要用来被外界调用的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY