运算符重载和友元函数

为什么要把这两个东西放在一起论述,是因为经常被同时结合运用。

先说运算符重载,运算符重载类比函数重载,但是比函数重载要复杂一些,也难理解一些,特别是运算符重载在不同参数个数上有不同的解释。

运算符重载分单目运算符和多目运算符的重载,有一些区别.

1.运算符的重载

举个二目运算符的例子:

class complex
{
	public:
		complex(){real=0;imag=0;}
		complex(double r,double i){real=r;imag=i;}
		complex operator + (complex &c2);//运算符重载函数
		void display();
	private:
		double real;
		double imag;
};
complex complex::operator + (complex &c2)//运算符重载函数
{
	complex c;
	c.real=real+c2.real;
	c.imag=imag+c2.imag;
	return c;
}

void complex::display()
{
	cout<<"("<<real<<","<<imag<<"i)"<<endl;
}

调用

complex c1(2,3),c2(4,-5),c3;
c3=c1+c2;
c3.display();
输出结果是:

(6,-2i)

实际上调用过程是:

c1.operator+(c2)



运算符重载规则

详细的规则不详说,

说两点需要注意的:
1)有5个不能重载

.(成员访问运算符)

*(指针访问运算符)

::

sizeof

?:

2)重载运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应有一个是类对象(或类对象的引用),也就是说,参数不能全部是c++的标准类型

如:

int operator +(int a,int b)

{

return (a-b);

}

这样是不对的,因为都是c++标准类型

应该这样

complex operator +(int a,complex &c)
{
	return complex(a+c.real,c.imag);
}
在这里说明下之前说的,参数个数的问题,在这里是两个参数在调用时应该是这样:

c3=5+c2;

所以之前类中的对+的运算符重载也可以写成两个参数的形式,即:

complex operator +(complex &c1,complex &c2);


再举个单目运算符(++)的例子:

class time
{
	public:
		time(){min=0;sec=0;}
		time(int m,int s):min(m),sec(s){}
		time operator ++();
		void display();
	private:
		int min;
		int sec;
};
time time::operator()
{
	if(++sec>=60)
	{
		sec-=60;
		++min;
		return *this;
	}
}
void time::display()
{
     cout<<min<<":"<<sec<<endl;
}


调用:

time t1(34,0)
while(true)
{
	++time;
        sleep(1);
}


运行情况如下:

34:1

34:2

.

.

.

34:59

35:0

35:1

.

.

.

上述的前置单目运算符,那自加后置运算符如何实现

例子如下:

time time::operator++(int)//参数中用int说明是后置运算符,这是c++约定的规则
{
	time temp(* this);
	sec++;
	if(sec<=60)
	{
		sec-=60;
		++min;
	}
  return temp;
}
在参数中填写int表示是后置运算符,因为++运算符结合律是从右向左的,所以后置++需要实现先取值,后自增的功能,所以需要一个临时对象保存当前对象的状态,并返回临时变量,即对象自增前的变量值。


最后是重载流运算符:
以插入流运算符举例“<<”,为什么要单独说呢,因为,流运算符需要实现对多个对象的输出


class complex
{
	public:
		complex(){real=0;imag=0;}
		complex(double r,double i){real=r;imag=i;}
		complex operator + (complex &c2);
		friend ostream &operator<<(ostream &,complex &);//运算符重载
	private:
		double real;
		double imag;
};

ostream &operator <<(ostream &output,complex &c)//运算符重载函数实现
{
	output<<"("<<c.real<<","<<c.imag<<"i)"<<endl;
	return output;
}

调用

complex c1(2,3),c2(4,-5),c3;
c3=c1+c2;
cout<<c3;

输出结果:

(6,-2i)


如果是

cout<<c3<<c2;

重载运算符是如何实现的呢?

这里我们注意到

ostream &operator<<(ostream &output,complex &c);

返回值是ostream 对象的引用,在函数实现中是返回的output这个引用,而output引用的就是cout这个输出流对象,这样在上述cout<<c3<<c2可以分开理解(cout<<c3)<<c2

这样在cout<<c3执行完之后相当于有执行一遍,cout<<c2,这样可以达到依次输出多个对象的目的。


2.友元函数

其实还有一个大的范围叫做友元,包括友元函数,友元类等等,在这里通过友元函数来说明友元的思想,和作用,这样就可以把一类的问题都能解决

在上述的插入流运算符重载中,用到了友元函数,友元就是朋友的意思,顾名思义就是说朋友能用的私人物品,区别一般的人,这样友元就能够访问类对象的私有成员了,这个就是友元的核心思想,但是这样容易破坏类的封装性。


class complex
{
	public:
		complex(){real=0;imag=0;}
		complex(double r,double i){real=r;imag=i;}
		complex operator + (complex &c2);
		friend ostream &operator<<(ostream &,complex &);//运算符重载
	private:
		double real;
		double imag;
};

ostream &operator <<(ostream &output,complex &c)//运算符重载函数实现
{
	output<<"("<<c.real<<","<<c.imag<<"i)"<<endl;
	return output;
}
再看下这个例子,运算符重载函数并不是类的成员函数,但是却可以访问类中的私有成员,因为在类中我们申明了该函数为友元函数


那如果友元函数为类的成员函数,该如何实现,该如何运用呢

举例如下:

class Date;
class Time
{
	public:
		Time(int,int,int);
		void display(Date &);
	private:
		int hour;
		int min;
		int sec;
};

class Date
{
	public:
		Date(int,int,int);
		friend void Time::display(Date &);
	private:
		int month;
		int day;
		int year;
};

Time::Time(int h,int m,int s):hour(h),min(m),sec(s){}

void Time::display(Date &d)
{
	cout<<d.month<<"/"<<d.day<<"/"<<d.year<<endl;
	cout<<hour<<":"<<min<<":"<<sec<<endl;
}

Date::Date(int m,int d,int y):hour(h),day(d),year(y){}

int main()
{
	Time t1(10,13,56);
	Date d1(12,25,2004);
	t1.display(d1);
	return 0;
}

用法看下代码就能够明白,就是实现在类中能用另外类的私有成员,用得比较少,在小的模块内部可能会运用到

主要是思想指导就好


最后说下友元类

class B;

class A

{

friend B;

}

这样B中的所有函数都是A类的友元函数。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值