C# · 12月 20, 2021

面向对象C++之(八)运算符重载

发现问题:

1.重载自增自减运算符:为什么重载自增(减)运算符并分情况讨论时,前置单目运算符的函数返回值必须为引用?

首先这是个伪命题。。只是课本和现在的教程上大部分都这么写了。引用作为返回值相比类好处更能减少程序开销。前几章我们学过调用构造函数(析构)的第三种情况,那就是作为函数返回值的时候,返回值会自动创建一个临时的副本并调用构造、析构函数。而如果我们用引用作为返回值的话,就省去了这些过程。

以复数运算为例,如果用传统办法:

#include

using namespace std;

class complex{

private:

double r,i;

public:

complex(double a,double b):r(a),i(b){}

void Show(){

cout<<r<<' '<<i<<endl;}

complex operator ++(int k);

complex operator ++();

};

complex complex::operator ++(int k){

complex t(r,i);

r++;

i++;

return t;

}

complex complex::operator ++(){

r++;

i++;

return complex(r,i);

}

int main(int argc,char** argv) {

complex a(1.0,3.0);

a++;

++a;

a.Show();

/////

complex b=a++;

b.Show();

complex c=++a;

c.Show();

return 0;

}

对比我们把complex的成员函数及其声明改成下面的情况:

complex &complex::operator ++(){

r++;

i++;

return (*this);

}

依旧可以获得一样的结果。只是前一个前置自增就不好修改了,因为返回引用时,返回的对象永远是自己,而this指向的值都已经改变了,所以无法做到返回引用。 

3 5

3 5

5 7

无参表和int参数表作为区分的重载,没有太多本质原因,就是为了单纯的区分前置与后置。 

2.重载输入输出运算符:cout与ostream(cin与istream)为什么要这么写?各自的本质是什么?

以前者为例子,ostream是一个类名,而cout是ostream的对象,它们都在iostream中获得定义,并通过调用实例化的对象cout来控制输出。因此如果要重载<<的话,就需要对cout上属的ostream类重载。

#include

using namespace std;

/* run this program using the console pauser or add your own getch,system(“pause”) or input loop */

class complex{

private:

double r,i;

public:

complex(double a=1.0,double b=2.0):r(a),i(b){}

friend ostream &operator <<(ostream &os,const complex &c);

};

ostream &operator <<(ostream &os,const complex &c){

os<< c.r << "+"<<c.i<<'i';

return os;

}

int main(int argc,char** argv) {

complex a;

cout<

return 0;

}