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修饰符),相当于一个变量的值一直在发生变化;
- 这段代码是标准库中提供的例子。