本文章是作者根据史蒂芬·普拉达所著的《C++ Primer Plus》而整理出的读书笔记,如果您在浏览过程中发现了什么错误,烦请告知。另外,此书由浅入深,非常适合有C语言基础的人学习,感兴趣的朋友可以自行阅读此书籍。
运算符重载
我们先了解下函数重载的概念,函数重载,也叫函数多态,指的是用户可以定义多个名称相同但特征标(参数列表)不同的函数,函数重载可以用同名的函数来完成相同的基本操作,即使这种操作被用于不同的数据类型。
运算符重载也是一种形式的C++多态,它将重载的概念扩展到运算符上,允许赋予C++运算符多种含义。实际上,很多C++(包括C语言)运算符已经被重载。例如,将*运算符用于地址,将得到存储在这个地址中的值;但将它用于两个数字时,得到的将是它们的乘积。C++根据操作数的数目和类型来决定采用哪种操作。
C++允许将运算符重载扩展到用户定义的类型。例如,允许使用+将两个对象相加。编译器将根据操作数的数目和类型决定使用哪种加法定义。重载运算符可使代码看起来更自然。
运算符函数的格式如下:
operatorop(argument-list)
例如,operator+()重载+运算符,operator()重载运算符。op必须是有效的C++运算符,不能虚构一个新的符合。比如不能有operator@()这样的函数,因为C++中没有@运算符。
假设有一个Student类,我们为它定义了一个,operator+()成员函数,目的是将两个Student对象的总分相加。假设st1,st2,st3都是类对象,那么我们就可以这样写:
st3 = st1 + st2;
编译器发现,操作数是Student类对象,因此使用相应的运算符重载函数替换上述运算符:
st3 = st1.operator+(st2);
然后该函数隐式地使用st1(调用了方法),而显示地使用st2对象(被作为参数传递),来计算总和,并返回这个值。更重要的是,可以使用简单的+运算符表示法,而不必使用笨拙的函数表示法。
运算符重载示例,设计一个时间类
假设我们上午工作花了2小时35分钟,下午工作花了4小时40分钟,我们想要计算下总共花了多少时间,但要相加的单位与内置类型不匹配。因此我们可以实现一个Time类,使其可以进行两个时间的加法。在使用运算符重载这个功能之前,我们先看看原始方法应该怎么做,我们需要定义一个求和的成员函数,可以对两个对象的小时和分钟分别求和,分钟如果大于60则小时+1。我们可以写出这样的类声明:
类声明如下:
//mytime0.hpp
#ifndef _MYTIME0_HPP_
#define _MYTIME0_HPP_
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; //此成员函数返回一个Time类对象,因为加法的结果需要一个新的变量来接收,比如 a = b + c;
void Show() const;
};
#endif
类方法实现如下:
//mytime0.cpp
#include <iostream>
#include "mytime0.hpp"
Time::Time()
{
hours = minutes = 0;
}
Time::Time(int h, int m)
{
hours = h;
minutes = m;
}
void Time::AddMin(int m)
{
int total_minutes = minutes + m;
minutes = total_minutes % 60;
hours += total_minutes / 60;
}
void Time::AddHr(int h)
{
hours += h;
}
void Time::Reset(int h, int m)
{
hours = h;
minutes = m;
}
Time Time::Sum(const Time& t) const
{
Time tmp;
int total_minutes = t.minutes + minutes;
tmp.minutes = total_minutes % 60;
tmp.hours += hours + t.hours + total_minutes / 60;
return tmp;
}
void Time::Show() const
{
std::cout << hours << " hours " << minutes << " minutes" << std::endl;
}
我们再写一个简单的测试程序:
//usetime0.cpp
#include <iostream>
#include "mytime0.hpp"
int main()
{
using std::cout;
using std::endl;
Time time_work;
Time time_work_morning(2, 35);
Time time_work_afternoon(4, 40);
cout << "morning work time: ";
time_work_morning.Show();
cout << endl;
cout << "afternoon work time: ";
time_work_afternoon.Show();
cout << endl;
time_work = time_work_morning.Sum(time_work_afternoon);
cout << "total time: ";
time_work.Show();
cout << endl;
return 0;
}
运行结果如下:
morning work time: 2 hours 35 minutes
afternoon work time: 4 hours 40 minutes
total time: 7 hours 15 minutes
可以看到,我们要计算两个Time类对象的和,需要这样调用:
time_work = time_work_morning.Sum(time_work_afternoon);
实际上,我们可以直接重载加法运算符,只要将Sum()的名称改为operator+即可。
修改后的类声明如下:
//mytime1.hpp
#ifndef _MYTIME0_HPP_
#define _MYTIME0_HPP_
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类对象,因为加法的结果需要一个新的变量来接收,比如 a = b + c;
void Show() const;
};
#endif
修改后的类方法实现如下:
//mytime1.cpp
#include <iostream>
#include "mytime1.hpp"
Time::Time()
{
hours = minutes = 0;
}
Time::Time(int h, int m)
{
hours = h;
minutes = m;
}
void Time::AddMin(int m)
{
int total_minutes = minutes + m;
minutes = total_minutes % 60;
hours += total_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 tmp;
int total_minutes = t.minutes + minutes;
tmp.minutes = total_minutes % 60;
tmp.hours += hours + t.hours + total_minutes / 60;
return tmp;
}
void Time::Show() const
{
std::cout << hours << " hours " << minutes << " minutes" << std::endl;
}
将Sum替换成operator+之后,我们既可以使用如下的方式来调用:
time_work = time_work_morning.operator+(time_work_afternoon);
也可以使用如下的方法使用:
time_work = time_work_morning + time_work_afternoon;
需要注意,在运算符表示法中,运算符左侧的对象是调用对象,运算符右边的对象是作为参数被传递的对象。
我们使用下这个新的类:
//usetime1.cpp
#include <iostream>
#include "mytime1.hpp"
int main()
{
using std::cout;
using std::endl;
Time time_work;
Time time_work_morning(2, 35);
Time time_work_afternoon(4, 40);
cout << "morning work time: ";
time_work_morning.Show();
cout << endl;
cout << "afternoon work time: ";
time_work_afternoon.Show();
cout << endl;
time_work = time_work_morning + time_work_afternoon;
cout << "total time: ";
time_work.Show();
cout << endl;
Time time_work_evening(2, 30);
cout << "evening work time: ";
time_work_evening.Show();
cout << endl;
time_work = time_work_evening.operator+(time_work);
cout << "total time: ";
time_work.Show();
cout << endl;
time_work = time_work_morning + time_work_afternoon+ time_work_evening;
cout << "total time: ";
time_work.Show();
cout << endl;
return 0;
}
运行结果如下:
morning work time: 2 hours 35 minutes
afternoon work time: 4 hours 40 minutes
total time: 7 hours 15 minutes
evening work time: 2 hours 30 minutes
total time: 9 hours 45 minutes
total time: 9 hours 45 minutes
我们在使用时,使用了这样的语句:
time_work = time_work_morning + time_work_afternoon + time_work_evening;
为什么可以这么做呢?那是因为+是从左向右的运算符,因此上述的语句会首先被转换成这样:
time_work = time_work_morning.operator+(time_work_afternoon + time_work_evening);
然后接着转换成这样:
time_work = time_work_morning.operator+(time_work_afternoon.operator+(time_work_evening));
time_work_afternoon.operator+(time_work_evening) 返回了一个Time对象,此对象是两者之和,然后该对象称为函数调用 time_work_morning.operator+()的参数,该调用返回time_work_morning与表示time_work_afternoon和time_work_evening之和的time对象的和。总之,最后的返回值是time_work_morning、time_work_afternoon和time_work_evening的和。
标签:示例,int,work,运算符,time,Time,重载,minutes From: https://www.cnblogs.com/superbmc/p/18100677