(1)对双目运算符而言,成员运算符重载函数参数表中含有一个参数,而友元运算符重载函数参数表中含有两个参数;对单目运算符而言,成员运算符重载函数参数表中没有参数,而友元运算符重载函数参数表中含有两个参数。
(2)双目运算符一般可以被重载为友元运算符重载函数或成员运算符重载函数,但有一种情况,必须使用友元函数:
例如,如果将一个复数与一个整数相加,可用成员运算符函数重载 “+”:
Complex operator+(int a){
return (real+a,imag);
}
若 com 和 com1 是类 Complex 的对象,则以下语句是正确的:
com1=com+100;
这条语句被 C++ 编译系统解释为:
com1=com.operator+(100);
由于对象 com 是运算符 “+” 的左操作数,所以它可以调用 “+”运算符重载函数 operator+,执行结果是对象 com 的数据成员 real 被加上一个整数 100。
然而,下面的语句是错误的:
com1=100+com; //编译错误,运算符 + 的左侧是整数
这条语句被 C++ 编译系统解释为:
com1=100.operator+(com);
由于运算符 “+” 的左操作数是一个整数 100,而不是该类的对象,编译时将出现错误。
如果定义一下的两个友元运算符重载函数:
friend Complex operator+(Complex com,int a){
//运算符“+”的左侧是类对象,右侧是整数
return Complex(com.real+a,com.imag);
}
friend Complex operator+(Complex com,int a){
//运算符“+”的左侧是整数,右侧是类对象
return Complex(a+com.real,com.imag);
}
当一个复数与一个整数相加时,无论整数出现在左侧还是右侧,使用友元运算符重载函数都能得到很好的解决。
#include
using namespace std;
class Complex{
private:
int real,imag;
public:
Complex(int r=0,int i=0); //构造函数
friend Complex operator+(Complex com,int a){
//定义友元运算重符载,"+"的左侧是类对象,右侧是整数函数
return Complex(com.real+a,com.imag);
}
friend Complex operator+(int a,Complex com){
//定义友元运算重符载,"+"的左侧是类对象,右侧是整数函数
return Complex(a+com.real,com.imag);
}
void show();
};
Complex::Complex(int r,int i){
real=r;
imag=i;
}
void Complex::show(){
cout<<"real="<<real<<",imag="<<imag<<endl;
}
int main(){
Complex com1(30,40),com2;
com2=com1+30;
com2.show();
com2=50+com1;
com2.show();
return 0;
}
(3)成员运算符函数和友元运算符函数都可以用习惯方式调用,也可以用它们专用的方式调用,下面列出了一般情况下运算符函数的调用形式:
习惯调用形式 | 友元运算符重载函数调用形式 | 成员运算符重载函数调用形式 |
---|---|---|
a+b | operator+(a,b) | a.operator+(b) |
-a | operator-(a) | a.operator-() |
a++ | operator++(a,0) | a.operator++(0) |
(4)C++ 的大部分运算符既可说明为成员运算符重载函数,又可说明为友元运算符重载函数。取决于实际情况和习惯来选择合适的运算符函数。
一般而言,对于双目运算符,将它重载为友元运算符比重载为成员运算符便于使用。对于单目运算符,则选择成员运算符较好。如果运算符所需的操作数(尤其是第一个操作数)希望有隐式类型转换,则运算符重载必须用友元函数。以下的经验可供参考: