C++运算符重载

来源:互联网 发布:微信怎么没有网络 编辑:程序博客网 时间:2024/06/10 01:08

运算符重载是C++的一项超级强大功能,通过关键字operator来实现,比如bool operator < (Type a,Type b){.....;}这样来重载<运算符

 运算符重载的规则 
运算符重载规则如下: 
 C++中的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已有的运算符。
 
 重载之后运算符的优先级和结合性都不会改变。
 
 运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造。一般来说,重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。
 
运算符重载形式有两种,重载为类的成员函数和重载为类的友元函数。
 
运算符重载为类的成员函数的一般语法形式为:
 
函数类型 operator 运算符(形参表)
 

  
函数体;
 

运算符重载为类的友元函数的一般语法形式为:
 
friend 
函数类型 operator 运算符(形参表)
 

  
函数体;
 

可以用作重载的运算符:

算术运算符:+,-,*,/,%,++,--

位操作运算符:&,|,~,^,<<,>>

逻辑运算符:!,&&,||

比较运算符:<,>,>=,<=,==,!=

赋值运算符:=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=

其他运算符:[],(),->,,(逗号运算符),new,delete,new[],delete[],->

下列运算符不允许重载:  .(成员访问运算符),.*(成员指针访问运算符),::(域运算符),sizeof(长度运算符),:(三目条件运算符)

运算符重载后,优先级和结合性:

用户重载新定义运算符,不改变原运算符的优先级和结合性。这就是说,对运算符重载不改变运算符的优先级和结合性,并且运算符重载后,也不改变运算符的语法结构,即单目运算符只能重载为单目运算符,双目运算符只能重载双目运算符。

 重载运算符有哪些限制:

(1) 不可臆造新的运算符。必须把重载运算符限制在C++语言中已有的运算符范围内的允许重载的运算符之中。

(2) 重载运算符坚持4个“不能改变”。

·不能改变运算符操作数的个数;

·不能改变运算符原有的优先级;

·不能改变运算符原有的结合性;

·不能改变运算符原有的语法结构。

红字标题内容摘自博客dingyuanpu

具体操作:

结构体情况下重载运算符

#include<iostream>using namespace std;struct date{int year;int month;int day;date(int x, int y, int z) :year(x), month(y), day(z) {}  //构造函数bool operator <(date a)  //重载双目比较运算符<,此时结构体自身作为一个实参,另一个由调用时给出,这里也可以使用引用{if (year != a.year)return year < a.year;else if (month != a.month)return month < a.month;elsereturn day < a.day;}void operator ! ()  //重载单目运算符!实现日期最小最大相互交替{if (year > 0 || month > 0 || day > 0)year = month = day = 0;elseyear = month = day = INT_MAX;}friend ostream& operator <<(ostream& cout, date& a)  //重载输出用到的<<运算符{cout << a.year << '-' << a.month << '-' << a.day;return cout;}};bool operator >(const date& a,const date& b)  //在结构体外重载双目运算符>,此时比较的两个参数都得由调用时给出,这里使用引用{if (a.year != b.year)return a.year > b.year;else if (a.month != b.month)return a.month > b.month;elsereturn a.day > b.day;}int main(){date a(1, 2, 3),b(1,2,4),c(0,0,0);!c;cout << ((a < b ? a: b)>c? (a < b ? a : b):c);    return 0;}

我们可以重载在结构体内,这时结构体自己作一个参数,重载在结构体外时参数全部需要由调用时给出。

类的情况下重载运算符:

类中,重载方式有两种,通过成员函数重载和通过友元函数重载

#include<iostream>using namespace std;class date{int year;int month;int day;public:date(int x, int y, int z) :year(x), month(y), day(z) {}  //构造函数bool operator <(date a)  //重载双目比较运算符<,此时类自身作为一个实参,另一个由形参传递过来,这里也可以使用引用{if (year != a.year)return year < a.year;else if (month != a.month)return month < a.month;elsereturn day < a.day;}void operator ! ()  //重载单目运算符!实现日期最小最大相互交替{if (year > 0 || month > 0 || day > 0)year = month = day = 0;elseyear = month = day = INT_MAX;}friend ostream& operator <<(ostream& cout, date& a);friend bool operator >(const date& a, const date& b);};ostream& operator <<(ostream& cout, date& a)  //重载输出用到的<<运算符{cout << a.year << '-' << a.month << '-' << a.day;return cout;} bool operator >(const date& a,const date& b)  //在类外重载双目运算符>,此时比较的两个参数都得由形参传递过来,这里使用引用{if (a.year != b.year)return a.year > b.year;else if (a.month != b.month)return a.month > b.month;elsereturn a.day > b.day;}int main(){date a(1, 2, 3),b(1,2,4),c(0,0,0);!c;cout << ((a < b ? a: b)>c? (a < b ? a : b):c);    return 0;}
其实两种情况很类似,函数可以自由访问结构体变量的所有成员,不需要像类一样通过friend声明来获得私有成员访问权限,而类的成员函数可以自由访问类的所有私有成员,也不需要用到friend,当类外函数要访问类的私有成员时就只能通过在类中先将这个函数声明为友元函数,然后再在类外定义,这样这个函数就能自由访问私有成员了。重载声明在结构体或者在类里,当前的类或者结构体自己本身当作为参数,重载声明在类外,因为没有this指针,则应通过形参表列出全部参数,由于不能改变原来的参数数量和优先级,缺少的参数应当在形参表中给出。