【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)

image-20221103185401061

下面这些函数绝不可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
posted @ 2023-10-01 18:35  travis-ge  阅读(16)  评论(0编辑  收藏  举报