上一节鸡啄米讲了多态性的概念和类型,多态有四种类型:重载多态、强制多态、参数多态和包含多态。这一节主要介绍重载多态中的运算符重载。
一.运算符重载的概念
为什么我们需要运算符重载?因为自定义数据类型有时也需要使用运算符进行某些运算,比如加法运算,但是预定义的运算符的操作数只能是基本数据类型,所以自定义数据类型的运算需要进行运算符重载。例如,有日期类Date声明如下:
class Date
{
public:
Date(int nYear, int nMonth, int nDay) { m_nYear=nYear; m_nMonth=nMonth; m_nDay=nDay; } // 构造函数
void show(); // 显示日期
private:
int m_nYear;
int m_nMonth;
int m_nDay;
};
假设我们声明了两个Date类的对象:Date date1(2011, 11, 1), date2(2012, 1, 6);。然后需要计算date1和date2所表示日期差多少天,也就是进行减法运算,最简单的就是用运算符“-”,但是如果直接写date2-date1,编译器会报错,因为编译器不知道怎样进行此减法运算。这就需要我们自己写程序来说明在对Date类对象进行“-”运算时,具体做哪些处理,也就是需要进行运算符重载。
总结一下,运算符重载就是为预定义的一些运算符增加新的意义,使其因操作数类型的不同而产生不同的操作。运算符重载实际上属于函数重载,因为在运算符重载中,不是运算符表达式而是调用运算符函数,操作数变成了运算符函数的参数,运算符函数的参数不同时调用不同的函数。这些与函数重载如出一辙。
二.运算符重载的规则
运算符重载的使用有如下规则:
1.运算符重载是为了让自定义数据类型能够使用预定义运算符,对预定义运算符进行重定义,但一般重定义的功能与原运算符的功能相似,运算符重载的参数个数与原运算符的操作数个数相同,而且至少有一个参数属于自定义数据类型。
2.运算符重载后其优先级和结合性都与原运算符相同。
3.除了类属关系运算符“.”、成员指针运算符“.*”、作用域分辨符“::”、sizeof运算符和条件运算符“?:”这五种运算符外,其余C++运算符都能重载,而且只有C++中已有的运算符可以重载。
“.”和“.*”不能重载是为了保证其功能不被改变,sizeof运算符和作用域分辨符的操作数不是一般的表达式,而是类型,所以也不能重载。
运算符重载后能作用于类的对象的话,最容易想到的重载形式是类的成员函数,其次就是类的友元函数。
运算符重载为类的成员函数时的声明形式为:
函数类型 operator 运算符(参数表)
{
函数体;
}
函数类型是运算符重载的返回值类型。operator是声明和定义运算符重载时的关键字。运算符就是需要重载的运算符,比如“+”或“-”,但不能是“.”、“.*”、“::”、sizeof或“?:”。参数表列出重载运算符的参数及类型,这里当重载运算符不是后置“++”或“--”时,参数的个数比原运算符的操作数个数少一个,因为类的对象调用运算符重载成员函数时,自己的数据可以直接访问,不需要在参数表中传递,所以参数表中就不必列出该对象本身了。
运算符重载为类的友元函数时的声明形式为:
friend 函数类型 operator 运算符(参数表)
{
函数体;
}
与上面运算符重载为类的成员函数时不同的是,在函数类型前需要加关键字friend。另外,运算符重载友元函数访问类的对象的数据时,必须通过类的对象名访问,所以此友元函数的所有参数都需要进行传递,参数个数与原运算符的操作数个数相同。
大家以后在软件开发中用了运算符重载后,会体会到复杂类型数据也能进行加减运算的方便的。这让我们的程序书写更简单,可读性更高,更易维护,最终提高软件开发效率。
今天就先讲到这了,主要是让大家了解下运算符重载的概念,及运算符重载的规则。至于运算符如何重载为类的成员函数和类的友元函数,后面会细讲。欢迎大家在鸡啄米博客留言,相互学习。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。