分类: C/C++
2008-03-12 12:34:53
操作符重载将重载的概念扩展到操作符上,允许赋予C++操作符多种含义。实际上,很多C++(也包括C语言)操作符已经被重载。例如,将*操作符用于地址,将得到存储在这个地址中的值;但将它用于两个数字时,得到的将是它们的乘积。C++根据操作数的数目和类型来决定采用哪种操作。
C++允许将操作符重载扩展到用户定义的类型,例如,允许使用+将两个对象相加。编译器将根据操作数的数目和类型决定使用哪种加法定义。
要重载操作符,需使用被称为操作符函数的特殊函数形式。格式如下:
operator op(argument-list)
其中,op是将要重载的操作符。例如,operator+()重载+操作符,operator*()重载*操作符。op必须是有效的C++操作符,不能虚构一个新的符号。例如,不能有operator@()这样的函数,因为C++中没有@操作符。但是,operator[]()函数将重载[]操作符,因为[]是数组索引操作符。例如,假设有一个Saleperson类,并为它定义了一个operator+()成员函数,以重载+操作符,以便能够将两个Saleperson对象的销售额相加,则如果district2、sid和sara都是Saleperson类对象,便可编写这样的等式:
district2 = sid + sara;
编译器发现,操作数是Saleperson类对象,因此使用相应的操作符函数替换上述操作符:
district2 = sid.operator+(sara);
下面,通过范例对操作符重载进行阐述,然后再讨论操作符重载的一些限制。
//time.h
#ifndef DFAF_H_
#define DFAF_H_
class Time
{
private:
int hours;
int minutes;
public:
Time();
Time(int h, int m = 0);
void addMin(int m);
void addHr(int h);
void reset(int h = 0, int m = 0);
Time sum(const Time & h) const;
void show() const;
};
#endif
//time.cpp
#include "time.h"
#include
Time::Time()
{
hours = 0;
minutes = 0;
}
Time::Time(int h, int m)
{
hours = h;
minutes = m;
}
void Time::addHr(int h)
{
hours += h;
}
void Time::addMin(int m)
{
minutes += m;
hours += minutes / 60;
minutes %= 60;
}
void Time::reset(int h, int m)
{
hours = h;
minutes = m;
}
Time Time::sum(const Time &t) const
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum;
}
void Time::show() const
{
std::cout << hours << " hours." << minutes << " minutes." << std::endl;
}
//main.cpp
#include
#include "time.h"
int main()
{
using namespace std;
Time planning;
Time coding(2, 40);
Time fixing(5, 55);
Time total;
cout << "planning time = ";
planning.show();
cout << "coding time = ";
coding.show();
cout << "fixing time = ";
fixing.show();
total = coding.sum(fixing);
cout << "coding.sum(fixing) = ";
total.show();
return 0;
}
Time类提供了用于调整和重新设置时间、显示时间、并将两个时间相加的方法。当总的分钟数超过59时,会对小时和分钟数做出调整。下面重载加法操作符,使之能用在两个Time类对象之间,并实现时间的相加,所做的改变很简单,只要将sum()的名称改为operator+()即可。
改后的程序:
//time.h
#ifndef DFAF_H_
#define DFAF_H_
class Time
{
private:
int hours;
int minutes;
public:
Time();
Time(int h, int m = 0);
void addMin(int m);
void addHr(int h);
void reset(int h = 0, int m = 0);
Time operator+(const Time & h) const;
void show() const;
};
#endif
//time.cpp
#include "time.h"
#include
Time::Time()
{
hours = 0;
minutes = 0;
}
Time::Time(int h, int m)
{
hours = h;
minutes = m;
}
void Time::addHr(int h)
{
hours += h;
}
void Time::addMin(int m)
{
minutes += m;
hours += minutes / 60;
minutes %= 60;
}
void Time::reset(int h, int m)
{
hours = h;
minutes = m;
}
Time Time::operator+(const Time &t) const
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum;
}
void Time::show() const
{
std::cout << hours << " hours." << minutes << " minutes." << std::endl;
}
//main.cpp
#include
#include "time.h"
int main()
{
using namespace std;
Time planning;
Time coding(2, 40);
Time fixing(5, 55);
Time total;
cout << "planning time = ";
planning.show();
cout << "coding time = ";
coding.show();
cout << "fixing time = ";
fixing.show();
total = coding + fixing;
cout << "coding + fixing = ";
total.show();
Time morefixing(3, 28);
cout << "more fixing time = ";
morefixing.show();
total = morefixing.operator +(total);
cout << "morefixing.operator+(total) = ";
total.show();
return 0;
}
operator+()函数的名称使得可以使用函数表示法或操作符表示法来调用它。
那么,可以将两个以上的对象相加吗?例如,如果t1,t2,t3,t4都是Time对象,可以这样做吗:
t4 = t1 + t2 + t3;
首先看一下上述语句是如何转换为函数调用的。由于+是从左向右结合的操作符,因此上述语句首先被转换成下面这样:
t4 = t1.operator+(t2 + t3);
然后,参数本身再转成一个函数调用,结果如下:
t4 = t1.operator+(t2.operator+(t3));
所以,是合法的,而且返回值是t1,t2,t3之和。
下面详细介绍C++对用户定义的操作符重载的限制:
1.重载后的操作符必须至少有一个操作数是用户定义的类型,这将防止用户为标准类型重载操作符。因此,不能将减法操作符(-)重载为计算两个double值的和。
2.使用操作符不能违反操作符原来的句法规则。例如,不能将求模操作符(%)重载成使用一个操作数。
3.不能定义新的操作符。
4.不能重载下面的操作符:
sizeof——sizeof操作符
.——成员操作符
.*——成员指针操作符
::——作用域解析操作符
?:——条件操作符
typeid——一个RTTI操作符
const_cast——强制类型转换操作符
dynamic_cast——强制类型转换操作符
reinterpret_cast——强制类型转换操作符
static_cast——强制类型转换操作符
5.只能通过成员函数进行重载的操作符:
=——赋值操作符
()——函数调用操作符
[]——下标操作符
->——通过指针访问类成员的操作符