是重载啊(二)

运算符重载规则

我们平常使用普通的运算符的时候,都是系统为基本类型重载好的,因此可以直接用。

重载运算符的限制

  1. 一共大致有5个运算符不可以被重载
    点,点星,作用域运算符,双冒号和问号组成的条件运算符,sizeof
  2. 运算符被重载之后,它的优先级,结合性和操作数个数不变

重载运算符的语法形式

用成员或友元函数重载运算符

运算符函数可以重载为成员函数或友元函数,普通函数的话会增大程序的开销。
二者的关键区别在于成员函数具有 this 指针,友元函数没有this指针,这一区别也可以解释成员与友元在使用,书写方式上的不同。
但是不管是成员函数还是友元函数重载,在主函数里运算符的使用方法相同。
但传递参数的方式不同,实现代码不同,应用场合也不同。

  1. 一元运算符
重载为成员函数,解释为:
Object . operator op ()
操作数由对象Object通过this指针隐含传递
//这一块如果说不清楚this指针隐含传递,可以看后面的二元运算符和代码,这也是前面提到的成员函数和友元函数的关键区别的体现
重载为友元函数,解释为:
operator op (Object)
    操作数由参数表的参数Object提供 
  1. 二元运算符
重载为成员函数,解释为:
ObjectL . operator op ( ObjectR )
左操作数由ObjectL通过this指针传递,
右操作数由参数ObjectR传递,
重载为友元函数,解释为:
operator op ( ObjectL, ObjectR )
  左右操作数都由参数传递 

用成员函数重载

一元运算符的操作数,或者二元运算符的左操作数
类的对象时,定义重载算符函数为成员函数

 TriCoor operator + ( TriCoor t ) 
          { TriCoor temp ;
             temp.x = x+t.x ;  temp.y = y+t.y ;  temp.z = z+t.z ;
             return temp ;
          }
TriCoor operator = ( TriCoor t ) { x = t.x ;  y = t.y ;  z = t.z ;  return * this ; }
TriCoor operator ++ () { x ++ ;  y ++ ;  z ++ ;  return *this ; }

用友元函数重载

友元函数重载运算符常用于运算符的左右操作数类型不同的情况

  Complex  operator + ( Complex ) ;...
} ;   
//在类外进行说明
Complex Complex:: operator + (complex )
{

}
int   f ( )
{ Complex  z ( 2 , 3 ) ,   k ( 3 , 4 ) ;
   z = z + 27 ;	//对,因为后面的27可以经过构造函数构造
   z = 27 + z ;	//错

因此可以由上面的例子得出,在第一个参数需要隐式转换的情形下,使用友元函数重载运算符是正确的选择。
友元函数没有 this 指针,所需操作数都必须在参数表显式声明,传递连个参数,很容易通过构造函数实现类型的隐式转换。
C++中不能用友元函数重载的运算符有
= () [] ->
友元不能重载它们的原因是它们只能对当前对象操作,所以只能通过成员函数实现,因为友元函数没有this指针。

friend Complex operator+ ( const Complex & c1, const Complex & c2 ) ;
     ……
Complex operator + ( const Complex & c1, const Complex & c2 )
  { double r = c1.Real + c2.Real ;  
  double i = c1.Image+c2.Image ;
     return Complex ( r,  i ) ;
  }

几个典型运算符的重载

重载++与–

自增与自减有前置和后置两种形式,C++作出规定,前置形式重载为一元运算符函数,后置形式重载为二元运算符函数。
参数0是一个伪值,是用于区分前置与后置的形式,友元函数的返回类型是引用的类类型(返回类类型的引用)是为了减少函数返回时对象复制的开销。
代码实现:

class obj
{
public:
friend obj operator ++ (obj & );
friend obj opetator ++ (obj &,int);//伪参数用以区分
int value;
}
obj operator ++ (obj & a)//前置
{
a.value++;
return a;
}
obj operator ++ (obj & a,int)
{
obj temp(a);//复制构造函数,,以temp保存对象a的原值作为函数的返回值
a.value++;
return temp;
}

不能随便使用伪参数,会引发调用的二义性(现在还是不甚了解)

用成员函数写后置加加
obj obj:: operator ++ (int x)
{
	obj temp;
	temp.value=value;
	value+=x;
	return temp;
} 

重载赋值运算符

重载运算符[]和()

重载流插入和流提取运算符

(只有友元可以做到)

重载常用集大成

#include<iostream>
using namespace std;
class complex
{
	double a;
	double b;
public:
	complex(double m = 0, double n = 0)//构造函数
	{
		a = m;
		b = n;
	}
	friend complex operator+( complex& c1,  complex& c2);//友元函数重载+
	friend complex operator-(complex &c1, complex &c2);//友元函数重载-

	friend istream& operator>>(istream& input, complex& c);//友元函数重载>>,输入格式参考样例输入
	friend ostream& operator<<(ostream& output, complex& c);//友元函数重载<<,输出格式参考样例输出

	complex operator++();//成员函数重载前++
	complex operator++(int);//成员函数重载后++

	friend complex operator--(complex& c);//友元函数重载前--
	friend complex operator--(complex& c, int);//友元函数重载后--
};

istream& operator>>(istream& input, complex& c)
{
	input >> c.a >> c.b;
	return input;
}
ostream& operator<<(ostream& output, complex& c)
{
	output << "(" << c.a << "," << c.b << ")" << endl;
	return output;
}
complex operator +(complex& c1, complex& c2)
{
	complex c3;
	c3.a = c1.a + c2.a;
	c3.b = c1.b + c2.b;
	return c3;
}
complex operator -(complex& c1, complex& c2)
{
	complex c3;
	c3.a = c1.a - c2.a;
	c3.b = c1.b - c2.b;
	return c3;
}
complex complex:: operator ++()
{
	a++;
	return *this;
}
complex complex:: operator++(int)
{
	complex temp;
	temp.a = a;
	temp.b = b;
	a++;
	return temp;
}
complex operator--(complex& c)
{
	c.a--;
	return c;
}
complex operator--(complex& c, int)
{
	complex temp(c);
	c.a--;
	return temp;
}
int main()
{
	int i;
	complex c1, c2, c3;
	cin >> c1 >> c2;
	c3 = c1 + c2;
	cout << c3;
	c3 = c1 - c2;
	cout << c3;
	for (i = 1; i <= 3; i++)
		c3 = c1++;
	cout << c1 << c3;
	for (i = 1; i <= 3; i++)
		c3 = c2--;
	cout << c2 << c3;
	c3 = ++c1;
	cout << c1 << c3;
	c3 = --c2;
	cout << c2 << c3;
}
//思考题:
//operator+,operator - ,operator++,operator--函数的返回值类型可以改为引用(complex & )吗?为什么?
//输入
//分别输入c1和c2
//
//输出
//输出运算结果
//
//样例输入
//10
//20
//30
//40
//样例输出
//(40, 60)
//(-20, -20)
//(13, 20)
//(12, 20)
//(27, 40)
//(28, 40)
//(14, 20)
//(14, 20)
//(26, 40)
//(26, 40)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

如果树上有叶子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值