我的c++学习(8)运算符重载和友元
运算符的重载,实际是一种特殊的函数重载,必须定义一个函数,并告诉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中列出了不允许重载的运算符。