运算符重载的概念和规则

运算符重载的概念

为什么我们需要运算符重载?因为自定义数据类型有时也需要使用运算符进行某些运算,比如加法运算,但是预定义的运算符的操作数只能是基本数据类型,所以自定义数据类型的运算需要进行运算符重载。

例如,有日期类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。

另外,运算符重载友元函数访问类的对象的数据时,必须通过类的对象名访问,所以此友元函数的所有参数都需要进行传递,参数个数与原运算符的操作数个数相同。

大家以后在软件开发中用了运算符重载后,会体会到复杂类型数据也能进行加减运算的方便的。这让我们的程序书写更简单,可读性更高,更易维护,最终提高软件开发效率。

你可能感兴趣的:(C++入门)