运算符重载

所谓的运算符重载是指对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

例如:我们要将两个数组相加是一种很常见的现象,通常我们是用for循环来实现:

 for(int i=0;i<20;i++)

a[i]=b[i]+c[i];

在C++中,可以定义一个表示数组的类,然后重载+运算符。使得:

a=b+c;

运算符函数的定义与其他函数的定义类似,惟一的区别是运算符函数的函数名是由关键字operator和其后要重载的运算符符号构成的。运算符函数定义的一般格式如下:

  <返回类型说明符> operator <运算符符号>(<参数表>)

{

     <函数体>

}

两个运算符重载的示例

#include <iostream>
using namespace std;
class X
{
	int i;
public:
	X(int ii=0){i=ii;}
	X operator   +(const X &rx)
	{
		i+=rx.i;
		return X(i);
	}
	int GetI(){return i;}
};
int main()
{
	X a(1),b(3);
	cout<<(a+b).GetI()<<endl;
	return 0;
}
运行结果为4。

再举一个时间相加的例子:

#include <iostream>
using namespace std;
class Time
{
private:
	int hours;
	int minutes;
public:
	Time(){hours=minutes=0;}
	Time(int h,int m=0)
	{
		hours=h;
		minutes=m;
	}
	Time operator+(const Time & t)const
	{
		Time sum;
		sum.minutes=minutes+t.minutes;
		sum.hours=hours+t.hours+sum.minutes/60;
		sum.minutes%=60;
		return sum;
	}
	void show() const
	{
		cout<<hours<<" hours,"<<minutes<<" minutes";
	}
};
int main()
{
	Time planning;
	Time coding(2,40);
	Time fixing(5,55);
	Time total;

	cout<<"planning time=";
	planning.show();
	cout<<endl;

	cout<<"coding time=";
	coding.show();
	cout<<endl;

	cout<<"fixing time=";
	fixing.show();
	cout<<endl;

	total=coding+fixing;
	cout<<"coding+fixing=";
	total.show();
	cout<<endl;

	Time morefixing(3,28);
	cout<<"more fixing time=";
	morefixing.show();
	cout<<endl;
	total=morefixing.operator+(total);
	cout<<"morefixing.operator+(total)=";
	total.show();
	cout<<endl;

	return 0;
}
程序运行结果为:

分析一下这个函数,有两个构造函数,会根据所给数据的参数来选择用哪个构造函数,开始定义了一个没有参数的planing,所以选择的是默认构造函数,其中hours和minutes都设置为0,接着定义了2个有参数的

Time coding(2,40);
    Time fixing(5,55);

选择的是第二个构造函数,显示出来的,然后对于重载运算符也有两种使用方法,第一种就是把运算符重载当做函数调用使用:

total=morefixing.operator+(total);

另外一种方法就是运算符表示法:

total=coding+fixing;

基于友元函数的运算符重载的示例

根据前面缩写的知道,由于类的封装性质,类中的私有成员,在类外边的函数是无法访问的,然而为了某些编程需要,外边的函数要访问类里面的私有成员。C++提供了这种机制,就是友元函数。那为什么在运算符重载中需要友元函数。可以看下面在各分例子:

对上面时间Time类的乘法*运算符的重载可以通过定义一个类成员函数:Time operator *(double d)来实现。当表达式t=t1*2.5的时候,编译器就会调用t1.operator*(2.5)来完成运算。不过,如果表达式是t=2.5*t1呢?由于2.5在前面,并且并没有对2.5进行Time的类型转换函数的重载,所以无法进行表达式的计算。但是事实上,t1*2.5跟2.5*t1结果是没有区别的,如果实现这两种表达式的兼容呢?

一种方法是再实现一个全局函数来完成,当然了,它需要两个参数,一个是double,一个是Time,像这样Time operator * (double d,Time &t)。但是这个函数有一个问题是,作为非类成员函数,它无法访问类里面的私有成员数据,怎么办呢?友元出场!在函数的前面添加一个friend关键字,就可以搞掂。

下面是值得注意的几点:

1、参数为相同类型的二元运算符重载,事实上有两种方式,比如说Time的相加。一种是类成员函数Time operator+(&Time),另外一种就是使用友元函数:friend Time operator+(Time &t1,Time &t2)。可以选择二者之一,但不可以二者皆选,否则编译器会报错。

2、其实友元函数的实现可以使用非友元函数来实现,可以这样来实现一个全局函数:t=2.5*t1=operator*(2.5,t1);

<pre name="code" class="cpp">Time operator * (double d,const Time &t)
{
	Time result;
	long totalminutes=t.hours*d*60+t.minutes*d;
	result.hours=totalminutes/60;
	result.minutes=totalminutes%60;
	return result;
}

 
 

当运算符函数是一个成员函数时,最左边的操作数(或者只有最左边的操作数)必须是运算符类的一个类对象(或者是对该类对象的引用)。如果左边的操作数必须是一个不同类的对象,或者是一个内部类型的对象,该运算符函数必须作为一个友元函数来实现。

<strong>    </strong>#include <iostream>
using namespace std;
class Complex{
public:
	Complex(double r=0.0,double i=0.0)
	{
		real=r;
		image=i;
	}
	friend Complex operator+(const Complex&,const Complex&);
	void display();
private:
	double real;
	double image;
};

Complex operator+(const Complex &c1,const Complex &c2)
{
	return Complex(c1.real+c2.real,c1.image+c2.image);
}

void Complex::display()
{
	cout<<"("<<real<<","<<image<<"i)"<<endl;
}

int main()
{
	Complex c1(3,4),c2(5,-10),c3;
	c3=c1+c2;
	cout<<"c1=";c1.display();
	cout<<"c2=";c2.display();
	cout<<"c1+c2=";c3.display();
	return 0;
}












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值