运算符重载是通过创建运算符重载函数来实现的。
在类外定义的运算符重载函数
对于基本的数据类型,C++提供了许多预定义的运算符,如“ +、-、*、/、= ”等。但是若要把类 Complex 的两个对象 com2 和 com2 加在一起,是不能直接通过“ com1+com2 ”来实现的,因为类 Complex 的类型不是基本数据类型,而是用户自定义的数据类型,C++ 无法直接将两个 Complex 类的对象相加。
C++ 为运算符重载提供了一种方法,即定义一个运算符重载函数,其名字为 operator,后随一个要重载的运算符。例如,要重载“ + ”,应该写一个名字为 operator+ 的函数,其他也同样如此,如下表:
函数 | 功能 |
---|---|
operator+ | 加法 |
operator- | 减法 |
operator* | 乘法 |
operator< | 小于 |
······· | ······· |
例 1:使用运算符函数 operator+ 实现对象相加
#include<iostream>
using namespace std;
class Complex{
public:
double real;
double imag;
Complex(){
}
Complex(double r,double i){
real=r;
imag=i;
}
};
Complex operator+(Complex com1,Complex com2){
Complex temp;
temp.real=com1.real+com2.real;
temp.imag=com1.imag+com2.imag;
return temp;
}
int main(){
Complex com1(1.1,2.2),com2(3.3,4.4),total1,total2;
total1=operator+(com1,com2);
cout<<"real1="<<total1.real<<" "<<"imag1="<<total1.imag<<endl;
total2=com1+com2;
cout<<"real1="<<total2.real<<" "<<"imag1="<<total2.imag<<endl;
return 0;
}
执行结果:
注意:将两个对象相加,语句
total=com1+com2;
等同于
total=operator+(com1+com2);
说明:
C++ 对运算符重载制定了一些规则:
(1)C++ 中绝大部分的运算符允许重载,不能重载的运算符只有以下几个:
. 成员访问运算符
.* 成员指针访问运算符
:: 作用域运算符
sizeof 长度运算符
? 条件运算符
(2)只能对已有的 C++ 运算符进行重载,不允许用户自己定义新的运算符,例如,“ ** ”在有的程序语言中作为指数运算符,但是它不是 C++ 运算符,所以 C++ 语言编程时不能重载“ ** ” 。
(3)一般来说,重载的功能应当与原有的功能相似,例如“ + ” 实现加法,从理论上来说,通过重载可以将“ + ”重载为执行减法操作,但是这样违背了运算符重载的初衷,容易造成混乱。
(4)运算符重载函数的参数至少应有一个是类对象(或类对象的引用),即,运算符重弄在函数的参数不能全部是 C++ 标准类型,例如,下面定义运算符重载函数的方法是错误的:
int operator+(int x,int y){
return x+y;
}
这项规定的目的是,防止用户修改用于标准类型数据的运算符性质,也就是说,运算符重载函数的参数不能全部是 C++ 的标准类型。
(5)运算符重载函数可以是普通函数,也可以是类的成员函数,还可以是类的友元函数。
(6)一般而言,用于类对象的运算符必须重载,但是赋值运算符“=” 除外,不必用户进行重载。但在某些特殊情况下,例如数据成员中包含指向动态分配内存的指针成员时,使用系统提供的对象赋值运算符函数就不能满足程序的要求,在赋值时可能出现错误,这时,就需要用户自己编译运算符重载函数。
补充:
例 1 中的运算符重载函数是在类的外部定义的普通函数,这个运算符重载函数只能访问类中的公有数据成员,而不能访问类的私有数据成员。
实际上,类中的数据成员常常是私有成员或保护成员,因此运算符重载函数一般采用以下两种形式定义:
①定义为它将要操作的类的成员函数(简称为成员运算符重载函数);
②定义为类的友元函数(简称为友元运算符重载函数)。