运算符重载

 C++提供了新的数据类型称为类,对类的对象进行操作时,我们当然可以用函数完成一切操作。但是为了将操作表示得更加直观,我们可以将运算符重新定义,使得操作更容易理解。
 比如string类重载了+运算符,使用+可以把两个不同的字符串连接在一起,这种重新定义让程序员的使用更加方便也更加直观。我们将这种重新定义成为重载。
为了方便说明,我们用一个简单的类来做示例

class Complex {
  private:
    double real; //表示实部
    double imag; //表示虚部
  public:
    Complex operator+(const Complex& );
    ...
    Complex& operator=(const Complex& );
    ...
    friend std::ostream& operator<<(std::ostream& out, Complex& oth);
};

算数运算符的重载(+、-、*、/)

重载算术运算时,我们不希望改变参数的值。因此往往将参数列表都声明为const。同时,通常我们返回一个新的对象,表示计算结果。
我们用+来举例

Complex::Complex operator+(const Complex& oth) {
    Complex temp;
    temp.real = this->real + oth.real;
    temp.imag = this->imag + oth.imag;
    return temp;
}

当然你可以写出一个名为add的成员函数来负责相加,在实际的函数调用中,a.add(b)和a+b是没有区别的,编译器会自己把a+b转换为a.+(b)(注意:在这里我们将+看作是一个函数名),但是你觉得a.add(b)和a+b哪个更方便呢。

赋值运算符重载(=、+=、-=、*=、/=……)

重载赋值运算符和重载算术运算符有一点不同,主要的区别是在调用赋值运算符时会对this对象进行修改,同时,他也不需要返回一个新的对象,运算结果已经储存在了this对象里。因此,我们对于赋值运算符重载时往往返回类型是引用,返回值即当前对象(*this)。
我们用=来举例

Complex& Complex::operator=(const Complex& oth) {
    this->real = oth.real;
    this->imag = oth.imag;
    return (*this);
}

可能有同学会问,我们为什么要有返回值呢?也是,即使没有return一行的话,this指针的值已经发生了修改,我们赋值的目的已经达到了,不要返回值看起来是完全可以的,但是我们要考虑到C++中赋值是可以连续赋值的,比如

Complex a, b, c;
a = b = c ;

编译器会把这行赋值语句改写为a.=(b.=(c))。
在执行b=c之后,如果b.=(c)没有返回值,系统会为这个函数默认返回一个东西,我们姑且记为x。那么下一层函数就变成了a.=(x)。
x是一个Complex吗?多半不是,这样的话连续赋值就失效了。
所以,加入return (*this)可以支持C++语法里的连续赋值,这是必要的(反正也不费什么事嘛)。

输入输出重载

同样是为了方便程序员的目的,我们要输出一个复数的时候,难道每次都要写

Complex a;
cout << a.getReal() << '+' << a.getImag() << 'i' << endl;

这样做明显是不人道的。当然你也可以写一个toString函数将复数转换为一个字符串然后输出,但是依然不是很方便,因此我们选择将输出重载,使得cout可以识别Complex类的对象并且按照一定格式输出。

std::ostream& Complex::operator<<(ostream& out, Complex& oth) {
    out << oth.real << '+' << oth.imag << 'i' << endl;
    return out;
}

在进行了这样的重载之后,我们在程序里就可以直接cout一个复数了,并且是符合1+2i这种格式的。
当然对于复数的输出重载并不是这么简单,还要加入一些对于正负数或0的判断,但是这并不是我们今天的讨论内容了,博主也懒得再详细的写,毕竟课上已经被折磨了很久了。
对于输入来说,要把ostream改为istream,<<改为>>。
!!!注意,在头文件中要把它声明为友元!!!

其他操作符的重载

  • [],这个操作符的作用是取出第几个元素,比如[i]就代表取出第i个元素。
  • ++a和a++,前者对this对象进行操作后返回this对象,后者将this对象复制一个副本,对this对象进行操作之后,返回副本。因此我们之前可以认为a++是先递增再返回,++a则是先返回再递增。在增量运算符中,放上一个整数形参,就是后增量运行符,它是值返回,对于前增量没有形参,而且是引用返回
Complex& Complex::operator++() {
    this->real++;
    this->imag++;
    return (*this);
}
Complex Complex::operator++(int) {
    Complex bf = (*this);
    this->real += 1;
    this->imag += 1;
    return bf;
}

一些注意事项

  1. 不要严重的扭曲语义,改变了操作符重载方便使用的本意
  2. 不能改变参数的数目,比如把+改成三个数相加
  3. . 、.* 、:: 、? : 、sizeof,typeid这几个运算符不可以重载,()、[]、->和赋值运算符只能重载为成员函数。C++可以重载的函数是有限定的

这里写图片描述
4. 重载操作符时最好先确定它作为左值还是右值,做左值时返回引用(比如=),做右值时最好返回值(比如+)。
5. 有所疏漏,知识所限,敬请谅解,还望指出,闲时修改

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值