运算符重载函数既可以声明为类的成员函数,也可以声明为所有类之外的全局函数。
运算符重载函数作为类的成员函数
将运算符重载函数声明为类的成员函数时,二元运算符的参数只有一个,一元运算符不需要参数。之所以少一个参数,是因为这个参数是隐含的。
例如,上节的 complex 类中重载了加法运算符:
complex operator+(const complex & A)const;
当执行:
c3 = c1 + c2;
会被转换为:
c3 = c1.operator+(c2);
通过 this 指针隐式的访问 c1 的成员变量。
运算符重载函数作为类的成员函数
将运算符重载函数声明为全局函数时,二元操作符就需要两个参数,一元操作符需要一个参数,而且其中必须有一个参数是对象,好让编译器区分这是程序员自定义的运算符,防止程序员修改用于内置类型的运算符的性质。
例如,下面这样是不对的:
int operator + (int a,int b){
return (a-b);
}
"+"号原来是对两个数相加,现在企图通过重载使它的作用改为两个数相减。 如果允许这样重载的话,那么表达式 4+3 的结果是7还是1呢?显然,这是绝对禁止的。
如果有两个参数,这两个参数可以都是对象,也可以一个是对象,一个是C ++内置类型的数据,如:
complex operator+(int a, complex &c){
return complex(a+c.real, c.imag);
}
它的作用是使一个整数和一个复数相加。
更改上节的 complex 类,用全局运算符重载函数计算复数的和:
#include <iostream>
using namespace std;
class complex{
private:
double real; //实部
double imag; //虚部
public:
complex(): real(0.0), imag(0.0){ }
complex(double a, double b): real(a), imag(b){ }
void display()const{ cout<<real<<" + "<<imag<<"i"<<endl; }
friend complex operator+(const complex &A, const complex &B); //友元函数
};
//全局运算符重载
complex operator+(const complex &A, const complex &B){
complex C;
C.real = A.real + B.real;
C.imag = A.imag + B.imag;
return C;
}
int main(){
complex c1(4.3, 5.8);
complex c2(2.4, 3.7);
complex c3;
c3 = c1 + c2;
c3.display();
return ;
}
因为重载运算符函数要用到 complex 类的私有变量,所以我们将该函数声明为友元函数。当执行:
c3 = c1 + c2;
会被转换为:
c3 = operator+(c1, c2);
最后要说明两点:
- 只有在极少的情况下才使用既不是类的成员函数也不是友元函数的普通函数,原因是上面提到的,普通函数不能直接访问类的私有成员。
- 指针操作符“->”、下标操作符“[]”、函数调用操作符“()”和赋值操作符“=”只能以成员函数的形式重载。