运算符重载(operator overload)只是一种语法糖(syntactic suger),也就是说只是一种函数调用的方式。
首先需要明确的是,在仅仅只包含内置数据类型的表达式的所有运算符不能被改变。只有那些包含用户自定义类型的表达式才可以有 重载的运算符。
1.语法
returntype operator +(arguementlists)
{
}
此处的+代指所有可以重载的运算符。需要注意的是,重载的运算符必须基于已有的运算符,并且不能改变其本意的功能,例如对于运算符+,我们希望它在用户自定义类型运算中也展现加法的功能。
此外,重载的运算符不能改变运算符的优先级,也不能改变运算符的参数个数。
对于参数列表的参数个数,需要取决于两个因素:
1.运算符是一元的还是二元的。
2.运算符被定义为全局函数(对于一元是一个参数,对于二元是两个参数)还是成员函数(对于一元没有参数,对于二元是一个参数----这时,这个类的对象自动用作二元的左侧参数)。
2.特殊的运算符
首先,是一些不能重载的运算符
1. "sizeof"
2."typeid"
3."."成员访问
4.".*" 通过成员指针访问
5."? : "三元条件运算符
6. "::"域运算符
其次,是一些运算符的推荐的使用,一般来说,对于所有一元运算符,都建议重载为成员函数,对于一些二元的运算符,都建议重载为非成员的全局函数,但是也有一些特殊情况,例如:
1."=" "()" "[]" "->" "->*" 必须重载为成员函数
2."+= " "-=" "*=" "/=" "^=" "&=" |=" "%=" >>=" "<<="建议重载为成员函数
具体如下表:
3.示例
#include<cstdio>
#include<iostream>
using namespace std;
class real{
private:
int nume,deno;
public:
real() : nume(0),deno(0){};
real(double n,double d):nume(n),deno(d){}
real& operator=(const real&rv)
{
nume=rv.nume;
deno=rv.deno;
return *this;
}
const real operator-()
{
return real(-nume,-deno);
}
operator double()
{
return double(nume)/deno;
}
friend const real operator+(const real&lv,const real&rv);
friend ostream& operator <<(ostream&os,const real&a)
{
if(a.nume!=0)
return os<<a.nume<<" / "<<a.deno;
else return os<<" 0 "<<endl;
}
};
const real operator+(const real&lv,const real&rv)
{
int temp1=lv.nume*rv.deno+rv.nume*lv.deno;
int temp2=lv.deno*rv.deno;
return real(temp1,temp2);
}
int main()
{
real r1(1,2),r2(2,3),r3;
r3=r1+r2;
r3=r3;
double num=r3;
cout<<r3<<endl;
cout<<num<<endl;
}
分开来看:
1.operator+,作为一个二元运算符,重载为全局,在类中声明友元函数以后,
friend const real operator+(const real&lv,const real&rv);
在类外,
const real operator+(const real&lv,const real&rv)
{
int temp1=lv.nume*rv.deno+rv.nume*lv.deno;
int temp2=lv.deno*rv.deno;
return real(temp1,temp2);
}
2.operator = ,必须重载为类的成员函数
real& operator=(const real&rv)
{
nume=rv.nume;
deno=rv.deno;
return *this;
}
3.operator-,这里的-作为负号,是一个一元运算符,重载为成员函数
const real operator-()
{
return real(-nume,-deno);
}
4.operator double(),一个类型转换,可以将用户自定义的类转换为内置类型的变量
operator double()
{
return double(nume)/deno;
}
5.输出流函数,作用是可以将用户自定义类型,类似于内置类型一样输出,而不需要在外部访问类内成员,
friend ostream& operator <<(ostream&os,const real&a)
{
if(a.nume!=0)
return os<<a.nume<<" / "<<a.deno;
else return os<<" 0 "<<endl;
}
6.主函数,就是构造了1/2和2/3两个分数,进行加法和类型转换
int main()
{
real r1(1,2),r2(2,3),r3;
r3=r1+r2;
r3=r3;
double num=r3;
cout<<r3<<endl;
cout<<num<<endl;
}