重载,操作符的重载
所有的成员函数都隐含一个参数this,这是一个指针,谁调用这个函数,谁就是this,编译器会把调用函数的对象的地址作为this传给函数,this可以用,但是不能写在函数的输入参数中
返回对象最好是用reference,这样传递者无需知道接收者是以reference形式接受还是别的形式,反正传递者就传递了一个指针
运算符有
inline complex&
complex::operator += (const complex& r)
{
return __doapl(this, r);
}
// 复数中的+=运算符重载时,如果只是用于C1+=C2;则返回值可以是void,但是考虑到可能会用C1+=C2+=C3,
// 因此返回值必须为complex&
可能被连串使用,所以运算符最好不要返回void。返回的也不能用const,因为会改变
非成员函数的重载
函数无this,但是可以写inline
inline complex // 注意这里的返回值不是reference,是因为之前+=有等号,是把函数返回值返回给已经存
//在的变量,而这里是通过创建了一个complex(在return那里创建),离开这个函数这个complex就消失了,所
//以这里不能用reference,但是传入的参数可以是reference
operator + (const complex& x, const complex& y)
{
return complex(real(x) + real(y), imag(x) + imag(y));
}
inline complex
operator + (double x, const complex& y)
{
return complex(x + real(y), imag(y));
}
inline complex
operator + (const complex& x, double y)
{
return complex(real(x) + y, imag(x));
}
上面的情况考虑了复数相加的三种情况,其实还有加虚部的情况
总之,定义一个类
构造函数时要考虑默认值,以及初始化
每个函数都要考虑传递的是reference还是value,不管是传入参数还是返回参数,以及参数是否可以const
函数body外定义的函数还要记得写inline
函数还有默认参数this,它指向当前调用函数的对象
private:
double re, im;
friend complex& __doapl(complex *, const complex&); //注意这里传入的第一个参数是
//complex*,是*而不是&的原因是后面调用__doapl的地方返回的是complex&,是个指针地址,所以这里要用
//complex*来将地址的内容作为传入的参数
};
...
inline complex& // complex&是返回值类型,inline是内联函数关键字
__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);
}
成员函数与非成员函数的区别,为什么对<<的重载并不是写在.h文件里,而是在.cpp文件里?
因为操作符的重载一定是作用在左边的操作数上的,但这样使用时就变成了c1 << cout,即把cout作用在c1上,而只有成员函数有this作为第一个参数,所以为了变成cout<<c1,只能把<<的重载写成非成员函数,函数名之前就没有class名称。
ostream&
operator << (ostream& os, const complex& x) // cout是ostrean类,不知道这个类有多大,所以by
// reference,另外查手册知道cout所在的ostream在使用时会改变,所以不加const
{
return os << "(" << real(x) << "," << imag(x) << ")";
}
// 考虑到cout << c1 << endl,所以<<返回的是ostream类,另外也可以by reference