【C++】年月日计算器——操作符重载的应用(含完整代码,简洁)(二)

简介: 【C++】年月日计算器——操作符重载的应用(含完整代码,简洁)

四.基本运算符重载【前置++,后置++等】

1.机制说明:

1.如何设置返回类型?

前置的是【先赋值后使用】:返回的是本身(Date&接收)(引用提高效率)

后置的是【先使用后赋值】:返回的是临时变量(Date接收)(不用引用,因为临时变量出作用域即销毁,引用会变成野引用)

2.如何在定义与声明中区分前后置?

增加参数int,构成函数重载

2.代码展示:

类内声明:

 //增加这个int参数不是为了接收具体的值,仅仅是占位,跟前置++构成重载 
  Date& operator++();
  Date operator++(int);
  Date& operator--();
  Date operator--(int);

.c内实现:

// 前置++
Date& Date::operator++()
{
  *this += 1;
  return *this;
}
// 后置++
// 增加这个int参数不是为了接收具体的值,仅仅是占位,跟前置++构成重载
Date Date::operator++(int)
{
  Date tmp = *this;
  *this += 1;
  return tmp;
}
Date& Date::operator--()
{
  *this -= 1;
  return *this;
}
Date Date::operator--(int)
{
  Date tmp = *this;
  *this -= 1;
  return tmp;
}

五. 减法的重载(日期-日期)

技巧:

  • 预设大小:得以计算绝对值
  • 预设flag:得以实现最终结果

.c文件实现:

int Date::operator-(const Date& d) const
{
  Date max = *this;
  Date min = d;
  int flag = 1;
  if (*this < d)
  {
    max = d;
    min = *this;
    flag = -1;
  }
  int n = 0;
  while (min != max)
  {
    ++min;
    ++n;
  }
  return n * flag;
}

六.完整代码实现

头文件:

#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
class Date
{
  // 友元函数声明
  friend ostream& operator<<(ostream& out, const Date& d);
  friend istream& operator>>(istream& in, Date& d);
public:
  Date(int year = 1, int month = 1, int day = 1);
  void Print() const
  {
    cout << _year << "-" << _month << "-" << _day << endl;
  }
  Date(const Date& d)   // 错误写法:编译报错,会引发无穷递归
  {
    _year = d._year;
    _month = d._month;
    _day = d._day;
  }
  bool operator<(const Date& x) const;
  bool operator==(const Date& x) const;
  bool operator<=(const Date& x) const;
  bool operator>(const Date& x) const;
  bool operator>=(const Date& x) const;
  bool operator!=(const Date& x) const;
  int GetMonthDay(int year, int month);
  // d1 + 100
  Date& operator+=(int day);
  Date operator+(int day) const;
  Date& operator-=(int day);
  Date operator-(int day) const;
  Date& operator++();
  Date operator++(int);
  Date& operator--();
  Date operator--(int);
  int operator-(const Date& d) const;
  // 流插入不能写成成员函数?
  // 因为Date对象默认占用第一个参数,就是做了左操作数
  // 写出来就一定是下面这样子,不符合使用习惯
  //d1 << cout; // d1.operator<<(cout); 
  //void operator<<(ostream& out);
  /*int GetYear()
  {
    return _year;
  }*/
private:
  int _year;
  int _month;
  int _day;
};
ostream& operator<<(ostream& out, const Date& d);
istream& operator>>(istream& in, Date& d);

.c文件:

#include "Date.h"
Date::Date(int year, int month, int day)
{
  if (month > 0 && month < 13
    && day > 0 && day <= GetMonthDay(year, month))
  {
    _year = year;
    _month = month;
    _day = day;
  }
  else
  {
    cout << "非法日期" << endl;
    assert(false);
  }
}
bool Date::operator<(const Date& x) const
{
  if (_year < x._year)
  {
    return true;
  }
  else if (_year == x._year && _month < x._month)
  {
    return true;
  }
  else if (_year == x._year && _month == x._month && _day < x._day)
  {
    return true;
  }
  return false;
}
bool Date::operator==(const Date& x) const
{
  return _year == x._year
    && _month == x._month
    && _day == x._day;
}
// 复用
// d1 <= d2
bool Date::operator<=(const Date& x) const
{
  return *this < x || *this == x;
}
bool Date::operator>(const Date& x) const
{
  return !(*this <= x);
}
bool Date::operator>=(const Date & x) const
{
  return !(*this < x);
}
bool Date::operator!=(const Date& x) const
{
  return !(*this == x);
}
int Date::GetMonthDay(int year, int month)
{
  static int daysArr[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  //if (((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) && month == 2)
  if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
  {
    return 29;
  }
  else
  {
    return daysArr[month];
  }
}
Date& Date::operator+=(int day)
{
  if (day < 0)
  {
    return *this -= -day;
  }
  _day += day;
  while (_day > GetMonthDay(_year, _month))
  {
    _day -= GetMonthDay(_year, _month);
    ++_month;
    if (_month == 13)
    {
      ++_year;
      _month = 1;
    }
  }
  return *this;
}
// d1 + 100
Date Date::operator+(int day)  const
{
  Date tmp(*this);
  tmp += day;
  return tmp;
  /*tmp._day += day;
  while (tmp._day > GetMonthDay(tmp._year, tmp._month))
  {
    tmp._day -= GetMonthDay(tmp._year, tmp._month);
    ++tmp._month;
    if (tmp._month == 13)
    {
      ++tmp._year;
      tmp._month = 1;
    }
  }
  return tmp;
  */
}
Date& Date::operator-=(int day)
{
  if (day < 0)
  {
    return *this += -day;
  }
  _day -= day;
  while (_day <= 0)
  {
    --_month;
    if (_month == 0)
    {
      _month = 12;
      --_year;
    }
    _day += GetMonthDay(_year, _month);
  }
  return *this;
}
Date Date::operator-(int day) const
{
  Date tmp = *this;
  tmp -= day;
  return tmp;
}
// 前置++
Date& Date::operator++()
{
  *this += 1;
  return *this;
}
// 后置++
// 增加这个int参数不是为了接收具体的值,仅仅是占位,跟前置++构成重载
Date Date::operator++(int)
{
  Date tmp = *this;
  *this += 1;
  return tmp;
}
Date& Date::operator--()
{
  *this -= 1;
  return *this;
}
Date Date::operator--(int)
{
  Date tmp = *this;
  *this -= 1;
  return tmp;
}
// d1 - d2;
int Date::operator-(const Date& d) const
{
  Date max = *this;
  Date min = d;
  int flag = 1;
  if (*this < d)
  {
    max = d;
    min = *this;
    flag = -1;
  }
  int n = 0;
  while (min != max)
  {
    ++min;
    ++n;
  }
  return n * flag;
}
//void Date::operator<<(ostream& out)
//{
//  out << _year << "年" << _month << "月" << _day << "日" << endl;
//}
// 21:20继续
ostream& operator<<(ostream& out, const Date& d)
{
  out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
  return out;
}
istream& operator>>(istream& in, Date& d)
{
  int year, month, day;
  in >> year >> month >> day;
  if (month > 0 && month < 13
    && day > 0 && day <= d.GetMonthDay(year, month))
  {
    d._year = year;
    d._month = month;
    d._day = day;
  }
  else
  {
    cout << "非法日期" << endl;
    assert(false);
  }
  return in;
}
相关文章
|
3月前
|
C++
C++ 语言异常处理实战:在编程潮流中坚守稳定,开启代码可靠之旅
【8月更文挑战第22天】C++的异常处理机制是确保程序稳定的关键特性。它允许程序在遇到错误时优雅地响应而非直接崩溃。通过`throw`抛出异常,并用`catch`捕获处理,可使程序控制流跳转至错误处理代码。例如,在进行除法运算或文件读取时,若发生除数为零或文件无法打开等错误,则可通过抛出异常并在调用处捕获来妥善处理这些情况。恰当使用异常处理能显著提升程序的健壮性和维护性。
64 2
|
3月前
|
算法框架/工具 C++ Python
根据相机旋转矩阵求解三个轴的旋转角/欧拉角/姿态角 或 旋转矩阵与欧拉角(Euler Angles)之间的相互转换,以及python和C++代码实现
根据相机旋转矩阵求解三个轴的旋转角/欧拉角/姿态角 或 旋转矩阵与欧拉角(Euler Angles)之间的相互转换,以及python和C++代码实现
165 0
|
4天前
|
存储 并行计算 安全
C++多线程应用
【10月更文挑战第29天】C++ 中的多线程应用广泛,常见场景包括并行计算、网络编程中的并发服务器和图形用户界面(GUI)应用。通过多线程可以显著提升计算速度和响应能力。示例代码展示了如何使用 `pthread` 库创建和管理线程。注意事项包括数据同步与互斥、线程间通信和线程安全的类设计,以确保程序的正确性和稳定性。
|
25天前
|
Linux C语言 C++
vsCode远程执行c和c++代码并操控linux服务器完整教程
这篇文章提供了一个完整的教程,介绍如何在Visual Studio Code中配置和使用插件来远程执行C和C++代码,并操控Linux服务器,包括安装VSCode、安装插件、配置插件、配置编译工具、升级glibc和编写代码进行调试的步骤。
110 0
vsCode远程执行c和c++代码并操控linux服务器完整教程
|
27天前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
44 2
|
2月前
|
编译器 C++
【C++核心】函数的应用和提高详解
这篇文章详细讲解了C++函数的定义、调用、值传递、常见样式、声明、分文件编写以及函数提高的内容,包括函数默认参数、占位参数、重载等高级用法。
22 3
|
2月前
|
C++
继续更新完善:C++ 结构体代码转MASM32代码
继续更新完善:C++ 结构体代码转MASM32代码
|
2月前
|
C++ Windows
HTML+JavaScript构建C++类代码一键转换MASM32代码平台
HTML+JavaScript构建C++类代码一键转换MASM32代码平台
|
2月前
|
C++
2合1,整合C++类(Class)代码转换为MASM32代码的平台
2合1,整合C++类(Class)代码转换为MASM32代码的平台
|
2月前
|
前端开发 C++ Windows
C++生成QML代码与QML里面集成QWidget
这篇文章介绍了如何在C++中生成QML代码,以及如何在QML中集成QWidget,包括使用Qt Widgets嵌入到QML界面中的技术示例。