【4】参数传递与返回值
函数可以分为两种,一种是改变数值的,一种是不改变数值的。
只要是不改变数值的函数,在函数定义时,函数名()后加上const
参数传递
** 参数包括:通过值传递、引用传递、const引用传递**
参数传递时,传递引用,本质上是传递指针,速度上也相当于是传指针。
建议:所有的传参都用引用传递
返回值传递
建议:所有的返回值都用引用传递
总结:
- 数值都在private里面
- 参数都用reference来传,要不要加const ,取决于具体情况
- 返回值也尽量用reference传。但是局部变量不能用引用返回
- 在class的body中,定义方法时,该用canst的地方一定要用。
【5】操作符重载
操作符就是一种函数,可以重新定义
成员函数的操作符重载
对于C2+= C1,其中+=的操作符,是作用在C2的身上。
在写重载操作符的函数时,会有个默认的参数this,表示该操作符的作用对象,但是写的时候不需要写出来。
** 任何成员函数都有一个隐藏的this指针,指向调用者,谁调用了这个函数,this就指向它**,比如上面的C2+= C1,就是C2调用这个操作符,this就是指向C2
所有的有左右两个参数的操作符都是这样,作用在左边的参数身上,存在this指针。
return by reference语法分析
传递者无需知道接收者是以reference形式接收
下面的例子中,C1是传递者,重载函数中的参数const complex& r是接收者
由于存在+=操作符连续使用的情况,所以重载写的函数的返回值不能是void,最好是reference。
非成员函数的操作符重载
复数之间的运算,可以是复数+实数,复数+复数。所以下面就给了三个全局函数,没有this指针。
下面这些重载函数,绝不可用reference的返回值,因为他们返回的必定是个local object。
*+*符号,相加后的结果返回到temp object中。下面虚线框内的都是临时对象。
typename(),也是临时对象的一种写法,下面黄色行就是表示的两个临时对象。
以下的例子中,运算符*<<*有左右两个参数,重载<<的函数中,参数是ostream&和const complex,第一个参数不是const,是因为要将第二参数一直放到os中。返回值是ostream&,也是为了能连续多个使用<<操作符。
总结
- 构造函数的初始化要会使用
- 一定要考虑定义函数的时候,是否需要加const
- 参数的传递尽量考虑reference
- 返回的时候,也要尽量考虑reference
- 数据一般放在private,函数放在public。
#ifndef __COMPLEX__
#define __COMPLEX__
using namespace std;
#include <iostream.h>
class complex
{
public:
//每一个class都要去想构造函数,名称与class相同,没有return值
complex (double r= 0 , double i=0 )
: re(r),im(i) //构造函数一定要设初值
{}
//声明一个操作符重载的成员函数
complex& operator += (const complex&);
//设计每一个函数的时候,要考虑是否加const
double real() const { return re; }
double imag() const { return im; }
private:
double re, im;
//定义友元函数,要取private中的re,im
friend complex& __doapl (complex*, const complex&);
};
//在class本体之外,定义成员函数时,用inline修饰成员函数,则编译器会在编译期间尝试将该成员函数内联炸奶,以提高函数调用的效率;内联函数是一种编译器优化技术,它将函数的定义插入到调用该函数的地方,而不是通过函数调用的方式执行。这样可以减少函数调用的开销,提高程序的执行效率。
//return值是否要用引用,要考虑传递的东西是否是local object,即不是在这个函数本体中创建出来的,就可以用引用return
inline complex&
__doapl(complex* ths, const complex& r)
{
ths->re += r.re;
ths->im += r.im;
return *ths;
}
inline complex&
complex::operator += (const complex& r)
{
//定义函数,把执行+=的部分给另一个函数去做
return __doapl(this,r);
}
// 设计全局函数
inline complex
operator + (const complex& x, const complex& y)
{
//由于+,需要创建一个新的local object,所以用一种简单的方式,class名称后加上(),表示创建一个temp object,并且可以在括号内赋初值
return complex(real(x) + real(y), imag(x) + imag(y));
}
inline complex
operator + (const complex& x, double y)
{
return complex(real(x) + real(y));
}
inline complex
operator + (double x, const complex& y)
{
return complex(imag(x) + imag(y));
}
ostream&
operator << (ostream& os, const complex& x)
#endif