【C++侯捷】面向对象高级编程(二)
【C++侯捷】面向对象高级编程(二)
操作符重载1-成员函数
C++很大的特性,在C++中,操作符(+-等)就是一种函数,可以让人重新定义,比如“+”操作符,你可以定义他要加什么。数字、分数、石头等。
在以上一直使用的complex类中,本小节定义“+”操作。
编译器如何看待操作符?
例如,
{
complex c1(2,1);
complex c2(5);
c2 += c1;
}
这是一个二元操作符。编译器将这个符号作用到左边,如果这个符号有定义的话,那么即找到。
C++中,所有的成员函数都带有一个隐含的参数,this
即,
inline complex&
complex::operator += (const complex & r){
return __doapl (this,r);
}
相当于,
inline complex&
complex::operator += (this, const complex & r){
return __doapl (this,r);
}
this指调用者(作用者),不写,但在函数体可以用。
inline complex&
__doapl(complex * this, const complex& r}{
this->re += r.re;
this->im += r.im;
return *this;
}
这段代码是标准库中复数相加代码
return by reference
传递者无需知道接收者是以reference形式接收
在上段代码中,会产生疑问,return的是value,但函数定义返回型是&,有问题吗?
无问题。
这与设计者有关,如果设计的是接受reference则接受快;如果接受object,则接受慢。
这便是 return by reference的语法分析。二者是可以搭配的。
{
c3 += c2 += c1;
}
假如这样使用,就不能设计成void。
class body之外的各种定义
inline double imag(const complex& x){ //传参使用reference
return x.imag();
}
inline double real(const complex& x){
return x.real();
}
操作符重载2-非成员函数(无this)
下面这些函数绝不可return by reference,因为他们返回的必定是local object.
inline complex
operator + (const complex& x, const complex& y)
{
return complex(real(x) + real(y),
imag(x) + imag(y));
}
operator + (const complex& x, double y)
{
return complex(real(x) + y,
imag(x);
}
operator + (const complex& x, const complex& y)
{
return complex(x + real(y),
imag(y));
}
与之前不同的是,上述只是相加,如需使用,必须放入一临时变量里;而之前的则是相加放入左边。
temp object(临时对象) typename()
例如上述complex ()
,生命周期很短。
class body 之外的各种定义
inline complex
operator + (const complex& x){
return x;
}
inline complex
operator - (const complex& x){
return complex(-real(x), -imag(x)); //绝不可return by reference, 因为其返回的必定是个local object
}
operator <<
#include <iostream>
ostream&
operator << (operator& os, const complex& x){ //只有输出,没有改变,所以加const;对于第一个参数,考虑要不要引用,要 //不要加const,这里不能加,因为os是不断被<<右边改变的
return os << '(' << real(x) << ',' << imag(x) << ')';
}
{
complex c1(2,1);
cout<< conj(c1);
cout<<c1<<conj(c1); //cout 作为第一个参数(固有的),详情查手册
}
这个函数不可以写成成员函数,只能写成global。
对于上述函数定义中ostream&
型,由于我们对cout的目的是输出到屏幕(控制台),如果只是单个cout<<A
,是可以的,但是考虑cout<< A << B
这种形式, A
丢给cout
之后得到的还要接收B
,所以就不能用void型。
,至于要不要reference
, 由于不是局部内local value
,所以可以。再思考const
,由于不断改变,所以不可以。
COMPLEX类总结
- 默认构造函数写法
const
考虑要不要加,能加就加pass by reference
考虑return by reference
考虑- 数据尽可能放在
private
,函数绝大部分放在public