《C++ Primer Plus》学习笔记——操作符重载(一)
操作符重载简介
C++允许将操作符重载扩展到用户定义的类型,例如,允许使用+实现两个对象“相加”。
举例:两个数组的相加通常需要以下的for循环语句来实现:
for(int i = 0; i < 10; i ++)
sum[i] = a[i] + b[i]; //逐个逐个元素相加
如果定义一个表示数组的类,并重载了+操作符,便可以直接用以下语句来实现两个数组相加的功能:
sum = a + b; //重载操作符+后,两个对象直接相加
操作符函数格式
operator op(argument-list)
引例:常规方法实现Time类相加
Time类包含两个int类型的成员变量:hours和minutes。
两个Time对象相加,当分钟位的总和超过59时,必须向小时位进一位。例如1h30min + 1h45min = 3h15min。
Time类中使用Sum()函数实现时间相加操作。以下为Time类的成员函数Sum()的原型声明:
Time Sum(const Time & t) const;
Sum()函数中,调用对象为被加数,参数中的对象为加数,返回值为一个Time对象,该对象保存了两对象之和。
通过整除和模除来调整hours和minutes的值,实现两个Time对象的相加运算。
注意:这里的参数声明为引用,目的是为了提高效率。按值传递Time对象,代码功能相同,但传递引用会使速度更快、使用的内存更少。
以下为完整的Time类声明及定义代码。
Time类头文件如下:
//mytime0.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 & t) const;
void Show() const;
};
Time类实现文件:
//mytime0.cpp
#include<iostream>
#include "mytime0.h"
Time::Time(){
hours = minutes = 0;
}
Time::Time(int h, int m){
hours = h;
minutes = m;
}
void Time::AddMin(int m){
minutes += m;
hours += minutes / 60;
minutes %= 60;
}
void Time::AddHr(int h){
hours += h;
}
void Time::Reset(int h, int m){
hours = h;
minutes = m;
}
//Sum()函数通过整除和模除来调整hours和minutes的值
//调用对象为被加数,参数对象为加数,返回值为两对象之和
Time Time::Sum(const Time &t) const{
Time sum;
sum.minutes += minutes + t.minutes;
sum.hours += sum.minutes/60 + hours + t.hours;
sum.minutes %= 60;
return sum;
}
void Time::Show() const{
std::cout<<hours<<"hours, "<<minutes<<"minutes";
}
Time类测试代码如下:
//main.cpp
#include<iostream>
#include "mytime0.h"
int main(){
using std::cout;
using std::endl;
Time planning;
Time coding(2, 40);
Time fixing(5, 55);
Time total;
cout<<"planing time = ";
planning.Show();
cout<<endl;
cout<<"coding time = ";
coding.Show();
cout<<endl;
cout<<"fixing time = ";
fixing.Show();
cout<<endl;
total = coding.Sum(fixing);
cout<<"total time = ";
total.Show();
cout<<endl;
return 0;
}
输出结果如下:
planing time = 0hours, 0minutes
coding time = 2hours, 40minutes
fixing time = 5hours, 55minutes
total time = 8hours, 35minutes
例1:添加加法操作符实现Time类相加
要在Time类中重载加法操作符,只需将Sum()的名称改为operator+()即可。
将Time类的Sum()修改成operator+():
//mytime1.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 & t) const; //修改后
void Show() const;
};
//mytime1.cpp
#include<iostream>
#include "mytime1.h"
Time::Time(){
hours = minutes = 0;
}
Time::Time(int h, int m){
hours = h;
minutes = m;
}
void Time::AddMin(int m){
minutes += m;
hours += minutes / 60;
minutes %= 60;
}
void Time::AddHr(int h){
hours += h;
}
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 += sum.minutes/60 + hours + t.hours;
sum.minutes %= 60;
return sum;
}
void Time::Show() const{
std::cout<<hours<<"hours, "<<minutes<<"minutes";
}
函数operator+()和Sum()一样,由一个Time对象调用,将第二个Time对象作为参数,最后返回一个Time对象。
因此,可以像调用Sum()一样调用operator+()函数:
total = coding.operator+ (fixing); //法一:函数表示法
使用操作符重载后,我们还能使用一种更为简便和直观的操作符表示法:
total = coding + fixing; //法二:操作符表示法
注意:在操作符表示法中,操作符左侧的对象是调用对象,操作符右边的对象是作为参数被传递的对象。
上述两种表示法是等价的,都将调用operator+()方法,测试代码如下:
//main.cpp
#include<iostream>
#include "mytime1.h"
int main(){
using std::cout;
using std::endl;
Time planning;
Time coding(2, 40);
Time fixing(5, 55);
Time total;
cout<<"planing time = ";
planning.Show();
cout<<endl;
cout<<"coding time = ";
coding.Show();
cout<<endl;
cout<<"fixing time = ";
fixing.Show();
cout<<endl;
total = coding + fixing; //操作符表示法
//total = coding.operator+(fixing); //函数表示法
cout<<"coding + fixing = ";
total.Show();
cout<<endl;
Time morefixing(3,28);
cout<<"more fixing time = ";
morefixing.Show();
cout<<endl;
total = morefixing.operator+(total);
cout<<"morefixing.operator+(total) = ";
total.Show();
cout<<endl;
return 0;
}
输出结果如下:
planing time = 0hours, 0minutes
coding time = 2hours, 40minutes
fixing time = 5hours, 55minutes
coding + fixing = 8hours, 35minutes
more fixing time = 3hours, 28minutes
morefixing.operator+(total) = 12hours, 3minutes
此外,重载加法运算符后,将两个以上的对象相加仍然是合法的,如:
t4 = t1 + t2 + t3;
上述操作等价于以下函数调用:
t4 = t1.operator+(t2.operator+(t3));
例2:其他重载操作符
除了加法操作符,还有一些其他的操作符对Time类来说是有意义的。
下面为Time类重载减法和乘法操作符,实现两个时间相减和时间乘以一个因子的操作。
同理,需要创建两个函数:
operator-()和operator*()。
新的头文件如下:
//mytime2.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 & t) const;
Time operator-(const Time & t) const; //重载减法操作符
Time operator*(double n) const; //重载乘法操作符
void Show() const;
};
将新增的方法添加到实现文件中:
//mytime2.cpp
#include<iostream>
#include "mytime2.h"
Time::Time(){
hours = minutes = 0;
}
Time::Time(int h, int m){
hours = h;
minutes = m;
}
void Time::AddMin(int m){
minutes += m;
hours += minutes / 60;
minutes %= 60;
}
void Time::AddHr(int h){
hours += h;
}
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 += sum.minutes/60 + hours + t.hours;
sum.minutes %= 60;
return sum;
}
Time Time::operator-(const Time &t) const{
Time diff;
int tot1, tot2;
tot1 = t.minutes + 60 * t.hours;
tot2 = minutes + 60 * hours;
diff.minutes = (tot2 - tot1) % 60;
diff.hours = (tot2 - tot1) / 60;
return diff;
}
Time Time::operator*(double n) const{
Time result;
long totalminutes = (hours * 60 + minutes) * n;
result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}
void Time::Show() const{
std::cout<<hours<<"hours, "<<minutes<<"minutes";
}
测试代码:
//main.cpp
#include<iostream>
#include "mytime2.h"
int main(){
using std::cout;
using std::endl;
Time planning;
Time coding(4, 35);
Time fixing(2, 47);
Time total;
cout<<"planing time = ";
planning.Show();
cout<<endl;
cout<<"coding time = ";
coding.Show();
cout<<endl;
cout<<"fixing time = ";
fixing.Show();
cout<<endl;
total = coding + fixing; //操作法表示法:加法
cout<<"total time = ";
total.Show();
cout<<endl;
total = total * 1.5; //操作法表示法:乘法
cout<<"total * 1.5 = ";
total.Show();
cout<<endl;
total = coding - fixing; //操作符表示法:减法
cout<<"tcoding - fixing = ";
total.Show();
cout<<endl;
return 0;
}
输出结果如下:
planing time = 0hours, 0minutes
coding time = 4hours, 35minutes
fixing time = 2hours, 47minutes
total time = 7hours, 22minutes
total * 1.5 = 11hours, 3minutes
tcoding - fixing = 1hours, 48minutes