首页 > 其他分享 >第11章 使用类——运算符重载(一)一个简单的运算符重载示例(Time类对象的加法)

第11章 使用类——运算符重载(一)一个简单的运算符重载示例(Time类对象的加法)

时间:2024-03-29 23:44:26浏览次数:31  
标签:示例 int work 运算符 time Time 重载 minutes

本文章是作者根据史蒂芬·普拉达所著的《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

相关文章

  • 【C语言】运算符优先级全面解析
    目录前言运算符优先级概述运算符分类与优先级列表运算符优先级的实际应用示例1:乘法和加法的优先级示例2:使用括号改变运算顺序示例3:赋值运算符的优先级示例4:逻辑运算符的优先级总结前言    C语言作为编程世界中的一颗常青树,其精确的语法规则和运算符优先级......
  • 基本运算符及流程控制语句(顺序、分支、循环结构)
    昨日内容回顾【一】八大基本数据类型#【1】数字类型#(1)整数类型(int)#(2)浮点数类型(float)#【2】字符串类型(str)#【3】列表类型(list)#【4】布尔类型(bool)#【5】字典类型(dict)#【6】集合类型(set)#【7】元组类型(tuple\)#【二】整数类型#能代表整数,代表......
  • 运算符,分支了解
    1.关于字典类型#{"key":"value"}#key:可以是任意类型,但是不建议放,不可变数据类型,字符串2.元组类型(tuple)2.1作用元组(tuple)是一种不可变的序列类型,类似于列表,用于存储多个有序元素。元组与列表的主要区别在于元组的元素不能被修改、删除或添加,是不可变的数据类型。......
  • 05程序与用户之间进行交互_基本运算符_流程控制语句
    【一】程序与用户之间进行交互【1】什么是与用户交互交互的本质就是输入、输出用户交互就是人往计算机中input/输入数据,计算机print/输出结果【二】如何与用户交互【1】输入(input)用户输入一些内容,用户按下回车键后,input函数会返回用户输入的内容input接受所有的数据类型......
  • C++从入门到精通——函数重载
    函数重载前言一、函数重载概念二、函数重载的分类参数类型不同的函数重载参数个数不同的函数重载参数类型顺序不同的函数重载三、函数重载的具体代码展示main.cpp四、为什么为什么C++支持函数重载,而C语言不支持函数重载呢前言函数重载是指在同一个作用域内,可以定......
  • C语言运算符和表达式——增1和减1运算符
    目录增1和减1运算符一元运算符前缀增1/减1运算符后缀增1/减1运算符前缀与后缀对变量和表达式的影响稍微复杂一点的例子增1和减1运算符的优缺点增1和减1运算符增1运算符(Increment)++*使变量的值增加1个单位减1运算符(Decrement)--*使变量的值减少1个单位注意:操作数......
  • uniapp(全端兼容) - 最新移动端评论区讨论点赞回复功能,可发表文字或图片评论|点赞|回
    效果图在uniapp小程序/h5网页网站/安卓苹果app/nvue等(全平台完美兼容)开发中,实现评论区、讨论区功能详细教程,uniapp评论区用户可发布图片、视频、文字进行评论,其他用户可进行“无限级|盖楼评论区”,点赞评论、回复评论、删除评论(自动计算刷新,不影响布局),当评论大于n条时自......
  • 程序与用户交互&基本运算符
    目的与程序之间交流输入输出如何交互输入:input弹出输入框:input()弹出提示信息:input("pleaseinput:")弹出提示信息,并返回:user=input("....:"),print(user)注意点:输入的内容永远是字符串,需要强制转化为所需要类型。代码num1=input("pleaseinput:")num2=in......
  • 大模型提示工程之Prompt框架和示例
    今天和大家分享一下:大模型提示工程之Prompt框架和示例:TAG框架任务(Task): 开发一个新的手机应用,旨在帮助用户更好地管理他们的日常健康。行动(Action): 进行市场调研,设计用户友好的界面,开发核心健康跟踪功能,测试应用并收集用户反馈。目标(Goal): 在六个月内发布应用,并在发布后的......
  • C++取经之路(其二)——含数重载,引用。
    含数重载:函数重载是指:在c++中,在同一作用域,函数名相同,形参列表不相同(参数个数,或类型,或顺序)不同,C语言不支持。举几个例子:1.参数类型不同intAdd(intleft,intright){ cout<<"intAdd(intleft,intright)"<<endl; returnleft+right;}doubleAdd(doublele......