我的c++学习(8)运算符重载和友元

时间:2023-12-04 14:55:44

运算符的重载,实际是一种特殊的函数重载,必须定义一个函数,并告诉C++编译器,当遇到该运算符时就调用此函数来行使运算符功能。这个函数叫做运算符重载函数(常为类的成员函数)。

方法与解释

◆ 1、定义运算符重载函数的一般格式:
    返回值类型 类名::operator重载的运算符(参数表)
    {……}
operator是关键字,它与重载的运算符一起构成函数名。

例如定义复数相加:
complex complex::operator+(const complex &c)
{
       complex Temp(real+c.real , Image+c.Image) ;
       //创建了一个显式的局部对象Temp
       return Temp;
}

◆ 2、【例4.8】定义了复数类,可完成复数基本运算,并应用它进行复数运算。
在本例中重载了运算符“+”、“=”、“+=”和“*”、“/”,以及求模(绝对值)的函数abs(),可以进行复数运算。

(1)在做 c=c2+c3时,C++编译器把表达式c2+c3解释为: c2.operator+(c3) ;

(2)可以用隐式的临时对象替换显式的对象Temp,如例中重载的operator+(double),它执行复数与实数的加法。
Complex Complex::operator+(double d)
{
       return Complex(Real+d , Image);
       //隐式说明局部对象,没名字
}

(3)
complex complex::operator+(const complex &c)
{
       return complex(real+c.real , Image+c.Image) ;
}

使用引用类型变量作为运算符重载函数的参数,可以提高复数类型运算的效率。

在引用形式参数类型说明前加const关键字,表示被引用的实参是不可改变的,如程序员不当心在函数体中重新赋值了被引用的实参,C++编译器会认为出错。例子中其它运算符也是类似处理。

(4)在缺省的情况下,C++ 编译器为每个类生成一个缺省的赋值‘=’操作,用于同类的两个对象之间的相互赋值,缺省的语义是类成员逐个相互赋值。

对复数类 complex 如果没有重载赋值运算符 =,复数的缺省赋值语义是:
Complex &Complex::operator = (Complex& c)
{
       real = c.real;
       image = c.image
       return *this;
}

这种缺省的赋值操作格式对所有类是固定的,这种缺省的格式对复数是合适的,但对其他类缺省的赋值可能产生问题,那时就需要重载‘=’。

因为缺省的赋值操作返回一个复数的引用,所以它可以进行连续赋值如:a=b=c=d ;

(5)重载的运算符“+=”标准算法是:
Complex& Complex::operator +=(Complex & com)
{
       real += com.real;
       image += com.image;
       return *this;
}

运算符重载小结

◆ 1、运算符重载函数的函数名必须为关键字operator加一个合法的运算符。在调用该函数时,将右操作数作为函数的实参。

◆ 2、当用类的成员函数实现运算符的重载时,运算符重载函数的参数(当为双目运算符时)为一个或(当为单目运算符时)没有。运算符的左操作数一定是对象,因为重载的运算符是该对象的成员函数,而右操作数是该函数的参数,其类型并无严格限制。C++不允许重载三目运算符。

◆ 3、单目运算符“++”和“--”存在前置与后置问题。

  • 前置“++”格式为:返回类型 类名::operator++(){……}
  • 而后置“++”格式为:返回类型 类名::operator++(int){……}

后置“++”中的参数int仅用作区分,并无实际意义,可以给一个变量名,也可以不给变量名。

◆ 4、C++中只有极少数的运算符不允许重载,表4.1中列出了不允许重载的运算符。