运算符重载实质上还是函数的重载。
重载运算符的函数一般格式如下:
函数类型 operator 运算符名称(形参表)
{对运算符的重载处理}
举一个例子,实现对+运算符的重载,使之能用于两个复数相加:
#include<iostream> using namespace std; class Complex { public: Complex(){real = 0;imag = 0;} Complex(double r,double i){real =r;imag = i;}; Complex operator + (Complex& c2); //声明重载运算符“+”的函数 void display(); private: double real; double imag; }; Complex Complex::operator + (Complex& c2) //定义重载运算符“+”的函数 { Complex c; c.real = real + c2.real; c.imag = imag + c2.imag; return c; } void Complex::display() { cout<<"real = "<<real<<endl<<"imag = "<<imag<<endl; } int main() { Complex c1(3,4),c2(5,-10),c3; c3 = c1 + c2; //运算符"+”用于复数运算1 cout << "c3 = "; c3.display(); return 0; }
注意函数名是由operator + 组成的。对上面的运算符重载函数还可以写的更简单一些
Complex Complex::operator + (Complex & c2)
{return Complex(real+c2.real,imag +c2.imag);}
重载运算符有以下规则:
1,C++不允许定义新的运算符,只能对已有的C++运算符进行重载。
2,C++允许对大多数运算符进行重载,但以下几个不可以:
. (成员访问运算符)
* (成员指针访问运算符)
:: (域运算符)
sizeof (长度运算符)
?: (条件运算符)
前两个运算符不能重载是为了保证访问成员的功能不能改变,域运算符和sizeof运算符的运算
对象是类型不是变量或者一般表达式。不具备重载的特征。
3,重载不能改变运算对象的个数,不能改变运算符的结合性。
4,重载运算符的函数不能有默认参数,否则就改变了运算符参数的个数。
5,重载的运算符的参数至少有一个是类对象,比如不能直接对int类型进行重载:
int operator + (int a,int b)
{return (a-b);}
6,从理论上说,可以将任意一个运算符重载为任意执行的操作,但应该使重载运算符的功能类似于其作用于标准类型数据时所实现的功能。
运算符可以重载作为类成员函数和友元函数,这两者有什么区别呢:
首先上面的例子是将+作为类的成员函数定义的,那么将+作为类的友元函数应该这样定义:
在Complex类中声明:
friend Complex operator + (Complex& c,Complex& i);
在类外定义友元函数:
Complex operator + (Complex& c,Complex& I)
{return Complex(c.real + l.real,c.imag+l.imag;}
可以看到,将运算符重载函数作为类成员函数时,可以少写一个参数,因为它可以通过this指针去访问一个对象成员,但是
作为友元函数,必须有两个参数,同时一些重载要求必须使用友元函数,比如实现C3 = I+ C2,即运算符左侧的操作数属于C++
标准类型或是一个其他类,则该函数只能作为非成员函数。
总结起来,有以下习惯:
(1),C++规定,赋值运算符=,下标运算符[ ],函数调用运算符(),成员运算符->必须作为成员函数。
(2),流插入<<和流提取>>,类型转换运算符不能定义为类的成员函数,只能作为友元函数。
(3),一般将单目运算符和复合运算符重载为成员函数。
(4),一般将双目运算符重载为友元函数。