C++为预定义的数据类型提供了丰富的运算符集,以简单的符号定义运算,当然我们自己也可以重新定义运算符我们想要的运算形式。这就要运算符重载了。

1. 重载运算符的限制

可以重载的运算符有:

+  -  *  /  %  ^  %  |  ~  !  =  《  》  +=  -=  *=  /=  %=  ^=  &=  |=  <<  >>  <<=  >>=  ==  !=  <=  >=  &&  ||  ++  –  ->*  ’  ->  []  ()  new  delete

一下运算符不能被重载:

.(成员访问运算符)  .*(成员指针运算符)  ::(作用域符号)  ?:(条件运算符)  sizeof 

重载后基本语义不能变

不能变运算符的优先级

不能变运算符的结合性

不能变运算符的所需操作数

不能创建新的运算符,只能重载系统预定义的运算符。

2.重载语法形式

类型  类名::operator  op(参数表)  //op处输入要重载的运算符,类型是函数的返回类型,类名是要重载该运算符的类,函数名是“operatro op”,operator 是一个关键词,参数表传入操作数

{

  //定义操作

}

  class calculator 
 {
 public:
 double value ; 
 void  operator ++();    
 }
 void calculator :: operator ++()
 {
 if (value<65535)++value;
 else
 {cout <<"\n data flow!"<<endl;abort();} 12 }
void main ()
{
calcualtor counter;
++counter;  //counter.operator ++(); 两种调用方法
}

3.成员函数和友元函数来重载运算符:

(1)成员函数

重载一元运算符:需要一个操作数,重载函数的操作数由隐含的this指针传递,所以参数列表为空。

重载二元运算符:需要两个操作数,重载函数的左操作数由隐含的this指针传递,所以参数列表只有一个操作数。

class tricoor
{
double x,y,z;
publice :
   tricoor ( int mx=0,int my=0,int mz=0):x(mx),y(my),z(mz){};
   tricoor &    operator ++();
   tricoor &    operator =(tricoor  t);

}

tricoor & tricoor :: operator ++()
{
x++;
y++;
z++;
return *this;
}

tricoor & tricoor ::  operator =(tricoor  t)  /传入的参数就是调用时的右操作数。
{
x=t.x;
y=t.y;
z=t.z;
rerurn *this;    //*this 是左操作数,是调用该函数的对象。这里是返回类类型的引用,这样就既符合运算符的原本语义,又减少了函数返回时对匿名对数据的复制开销。
}

void main()
{
tricoor a(1,2,3),b,c,d;
c=a+b+c;
}

(2)友元函数

当运算符的左右操作数类型不同,用成员函数来重载就会遇上问题,例如:

class complex
{
double real,image;
publice :
complex (int a){real=a;image=0;};
complex (int a,int b){real=a;image=b;};
complex operator +(complex a)
{
real+=a.real;
image+=a.image;
};
}

void main()
{
complex z(1,2), k(2,3);
z=z+25;             //这样右操作数25就会传进形参,根据构造函数构建一个复数25,建立临时对象执行函数,是合理的
z=25+z;            //当解释为系统预定义的版本,但是z无法被转换成基本数据类型;当解释为重载版本时,25.operator+() 由于25这个整型数据无法驱动函数,也是失败的。
}

但是,如果用友元函数,传入的参数都是平等的,就不会有这种问题了。

重载一元运算符:传入一个参数;

重载二元运算符:传入两个参数。

例如:

class complex
{
double real,image;
publice :
complex (int a){real=a;image=0;};
complex (int a,int b){real=a;image=b;};
friend  complex operator +(const complex &c1,const complex &c2)     //加上const 是为了限制对实参只读。
{
double r=c1.real+c2.real;
double i=c1.image+c2.image;
return complex (r,i);            //显式调用构造函数,返回一个创建出来的匿名对象
};
};
void main ()
{
complex c1(1,2),c2(5,6),c3;
c3=c1+c2;
}

(3)当一个运算符的操作需要修改类对象的状态时,应该以成员函数重载,例如,左值操作数的运算符(=,*=,++等)应该用成员函数来重载。如果要用友元函数的话,那么就要使用引用参数来修改对象。

C++中不能用友元函数重载的运算符有:

= ()  【】  -> 

 

未完待续…

 

版权声明:本文为yesean原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/yesean/p/8665494.html