运算符重载

  • 格式:doc
  • 大小:29.00 KB
  • 文档页数:2

在C++中,只有类的成员函数和类的友元函数才能够访问类的私有数据成员,因此只有将运算符重载为数据类的成员函数或是友元函数时,才能使被重载的运算符应用于新的数据类型。

运算符重载为类的成员函数的一般语法形式为:
函数类型operator 运算符(形参表)
{
函数体;
}
运算符重载为类的友元函数的一般语法形式为:
friend 函数类型operator 运算符(形参表)
{
函数体;
}
当运算符重载为类的成员函数时,函数的参数个数比原来的操作个数要少一个;当重载为类的友元函数时,参数个数与原操作数个数相同。

原因是重载为类的成员函数时,如果某个对象使用重载了的成员函数,自身的数据可以直接访问,就不需要再放在参数表中进行传递,少了的操作数就是该对象本身。

而重载为友元函数时,友元函数对某个对象的数据进行操作,就必须通过该对象的名称来进行,因此使用到的参数都要进行传递,操作数的个数就不会有变化。

只能重载为成员函数的运算符
C++要求,像赋值“=”、下标“[]”、调用“()”、以及成员访问箭头“->”等,这些第一个操作数一定是本类对象的运算符,重载时必须被定义为类的成员函数,任何把这些运算符重载为非类成员函数的做法都会产生编译时刻的错误。

这样做的原因在于类的所有非静态成员函数都隐含有指向对象自己的this指针(类的友元函数不具有),如果将运算符重载为类的成员函数,则运算符的第一个操作数系统默认就是this对象(本类的对象)。

也正是由于this指针的存在,当运算符被重载为成员函数的形式时,第一个操作数不作为函数参数,这样一来,对于单目运算符可以不写参数,而双目运算符可以只写一个参数,即第二个操作数(或称右操作数)。

运算符重载为成员函数格式如下:
<函数返回值类型> operator <运算符名> (<参数表>);
例如有一个表示时间的time类,求将已有时间推后x小时后的时间,重载“+”运算符为time类的成员函数,格式如下:
time operator + (int x);
只能重载为友元函数的运算符
与第1)种情况正好相反,像插入运算符“<<”和提取运算符“>>”等第一个操作数一定不是本类对象的运算符,只能被重载为类的友元函数。

比如插入运算符“<<”的第一个操作数cout是系统定义类ostream类的全局对象,提取运算符“>>”的第一个操作数cin是系统定义类istream类的全局对象。

当运算符被重载为友元函数的形式时,函数参数的个数与运算符操作数的个数一致,即单目运算符需要一个参数,而双目运算符需要两个参数。

运算符重载为友元函数格式如下:
friend <函数返回值类型> operator <运算符名> (<参数表>);
同样以1)中的time类为例,重载“+”运算符为time类的友元函数,格式如下:
firend time operator + (time& t,int x);
根据应用情况选择重载形式的运算符
之所以某些运算符只能重载为成员函数或是友元函数,是由这些运算符的第一个操作数的类型决定的,第一个操作数一定是本类对象的运算符,重载时必须被定义为类的成员函数,第一个操作数一定不是本类对象的运算符,只能被重载为类的友元函数。

如果对运算符的第一个操作数的类型没有限制,那么这个运算符既可以被重载为成员函数,也可以被重载为友元函数。

在具体选择运算符的重载形式时,可以根据应用情况来决定。

双目运算符,如算术运算符“+”、“-”,关系运算符“>”、“<”等,有两个操作数,就存在三种情况:两个操作数都为类的对象;第一个操作数为类的对象、第二个操作数为其它数据类型;第一个操作数为其它数据类型、第二个操作数为类的对象。

显然,将运算符重载为类的成员函数无法处理第三种情况,而将运算符重载为类的友元函数时三种情况都可以处理。

因此,双目运算符最好重载为类的友元函数。

单目运算符只有一个操作数,既然是因为被用于新类型而重载,那么这唯一的操作数绝大多数情况下是用户定义类的对象,如果将其重载为类的成员函数,则可以通过this指针自由地访问本类的数据成员,不用设置参数;另外友元的使用会破坏类的封装,因此单目运算符最好重载为类的成员函数。

#include<iostream> // 这个就是1998年标准化以后的标准头文件#include<iostream.h> // 这个就是标准化以前的头文件
更本质上的区别就是iostream把标准C++库的组件放在一个名位std 的namespace里面。

而相对的iostream.h则将这些标准组件放在全局空间里,同时在标准化以后旧有的C标准库也已经经过改造了。

使用前者,就需要在代码中添加语句:using namespace std;。