欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++?Date類的具體使用(構(gòu)建,重載等)

 更新時間:2022年07月18日 09:52:17   作者:玄鳥軒墨  
本文主要介紹了C++?Date類的具體使用(構(gòu)建,重載等),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

寫在前面

我們今天寫一個Date類作為C++初始類的結(jié)尾,這里涉及到的知識,里面有很多運算符的重載,包括權(quán)限的問題,我們都已經(jīng)分享過了,所以大家不用擔心,這里算是一個總結(jié)吧.我這里用的的是Linux環(huán)境,主要是鍛煉自己的能力.

成果

我們要完成一個什么樣的Date類呢,大家可以搜一下時間計算器,我們就完成他們的功能,比如說加減300天或者看看兩個日期之間的天數(shù),這就是我們要完成的任務.

image-20220706150104866

準備工作

這里我們用三個文件來寫,分別是Date.h,Date.cpp,test.cpp.我們先把初始工作給做好了,我們先把框架各搭出來,后面要的功能一一補足.

Date.h

#include <iostream>
#include <assert.h>

using std::cout;
using std::endl;

class Date
{
public:
    
  Date(int year = 1900, int month = 1, int day = 1);
  //析構(gòu)函數(shù)
  ~Date();
  // 拷貝構(gòu)造
  Date(const Date& d);
private:
	int _year;
	int _month;
	int _day;
};

Date.cpp

#include "Date.h"

Date::Date(int year, int month, int day)
{
}

~Date()
{
}

Date(const Date& d)
{
}

test.cpp

#include "Date.h"
int main()
{
    
    return 0;
}

構(gòu)造函數(shù)

我們先來寫一下日期類的構(gòu)造函數(shù),本來這是沒有多少問題的,但是我們知道一個月的天數(shù)是有限制的,而且還有閏年于平年之分,這就考慮的有點難度了,但是這要符合我們的客觀規(guī)律.我們先來把思路捋順.

第一點 我們把年月份給對象,其中肯定都是大于0的整數(shù),這個是毋庸置疑的,第二步,我們要判斷這一年是平年還是閏年,第三步,要判斷給的月數(shù)的對應的天數(shù)是否合理.

我們分別用方法來完成自己的要求.

判斷平年 or 閏年

這個很簡單,記得去類里面聲明這個方法.

bool Date::isLeap(int year)
{
  assert(year > 0);
  return (year % 4 == 0 && year %100 != 0)
    || year % 400 == 0;
}

判斷天數(shù)是否合理

我們都知道每一月分都有固定的天數(shù),而且月份是肯定小于13的,

int Date::isLegitimate(int year,int month)
{
  
  static int monthDay[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
  assert(month > 0 && month < 13);
  assert(day > 0);
  //判斷閏年 && 而且 月份是 2 月
  if(isLeap(year) && month == 2)
  {
    return 29;
  }
  return monthDay[month];  
}

我來解釋一下我們定義數(shù)組的時候為什么用的是 static ? 我們知道,這是一個函數(shù),也就是說函數(shù)棧幀會在結(jié)束后銷毀,但是我們可能多次調(diào)用這個函數(shù),為了避免多次開辟和銷毀該數(shù)組的空間,這里直接用static修飾得了.

寫好構(gòu)造函數(shù)

到這里我們已經(jīng)寫好了的構(gòu)造函數(shù),沒必要在說其他了.

Date::Date(int year = 1900, int month = 1, int day = 1)
{
   if(year > 0 && month > 0 && month <13 && day <= isLegitimate(year,month))
    {
        _year = year;
        _month = month;
        _day = day;
    }
    else 
    {
        // 這里應該拋出一個異常 
        // 現(xiàn)在我還不太會 暫時用 assert代替
        assert(NULL);
    }
}

析構(gòu)函數(shù) & 拷貝構(gòu)造

說實話,這兩個函數(shù)我們不用寫,主要是我們沒有使用動態(tài)開辟空間,都是一些基本的內(nèi)容,編譯器生成的已經(jīng)完全夠了,這里大家看看就行了.

由于這兩個函數(shù)都不大,這里就聲明成內(nèi)聯(lián)函數(shù)函數(shù)吧,在類內(nèi)實現(xiàn).

// 析構(gòu)函數(shù)
inline ~Date()
{
  _year = 0;
  _month = 0;
  _day = 0;
}
 
// 拷貝構(gòu)造
inline Date(const Date& d)
{
  _year = d._year;
  _month = d._month;
  _day = d._day;
}

運算符重載

某種意義上,運算符重載才是我們今天的大頭,我們不是重載所有的運算符,而是要重載那些符合我們邏輯的,例如一個日期加上一個日期就沒有什么意義,這里就不會重載它.

邏輯運算符的重載

這個基本的邏輯運算符都有意義,這里我們一一給大家重載出來,同時也驗證一下.

重載 ==

這個很好寫,如果日期的年月日都相等,那么這兩個日期一定相等.

bool Date:: operator==(const Date& d) const
{
    return _year == d._year
        && _month == d._month
        && _day == d._day;
}

image-20220706164559795

重載 >

如果一個日期的年數(shù)比較大,那么它一定更大,如果相等,就比較月份,如果月份還相等,那就比較天數(shù),這就是這個的原理.

bool Date:: operator>(const Date& d) const
{
  return (_year > d._year)
    ||(_year == d._year && _month > d._month)
    ||(_year == d._year && _month == d._month && _day > d._day);
}

image-20220706165531482

重載 >=

只要我們完成了上面的兩個,后面就可以直接調(diào)用它們了,避免重復造輪子.

bool Date::operator>=(const Date& d) const
{
  return *this > d || *this == d;
}

image-20220706170227802

重載 <

從這里開始,我就不演示結(jié)果了,都是和之前的一樣.

我們知道,小于的對立面就是大于大于等于

bool Date::operator<(const Date& d) const
{
  return !(*this >= d);
}

重載 <=

小于等于的對立面是大于,我們已經(jīng)實現(xiàn)了.

bool Date::operator<=(const Date& d) const
{
  return !(*this > d);
}

重載 !=

這個更加簡單,不等于不就是等于的對立面嗎

bool Date::operator!=(const Date& d) const
{
  return !(*this ==  d);
}

算數(shù)運算符的重載

上面的都挺簡單的,這里算數(shù)運算符我們要重載的有加法,等于,減法,前置和后置++…有一定的額難度,尤其是加法和減法.

重載 =

等于的重載基本來說對于我們是沒有任何問題的,但是有一點是需要我們注意的,無論是C語言還是C++都是支持連等的,也就是a = b = c,那就意味者我們們重載等于的時候是要有返回值的.

Date& Date::operator=(const Date& d)
{
  // 避免 重復
  if(this != &d)
  {
    _year = d._year;
    _month = d._month;
    _day = d._day;
  }
  return *this;
}

重載 +

說實話,加號還是比較簡單的,我們首先要把給的天數(shù)判斷一下,假如要是小于零,就去調(diào)用重載的減號,后面我會實現(xiàn)減法的,這里先考慮好.

那么我們該如何把這個邏輯給完善好呢?第一步,就是把給的天數(shù)直接加到_day上面,如果還沒有超過當前月最大的天數(shù),我們就直接返回這個日期就可以了,否則就把日期減去當前月最大的天數(shù),當前月加一,注意,這里要明白,如果當前月是12月,我們直接把月份置為1,年加上一,這里要注意一點東西 ,我們不修改原來的日期

我們可以分為三種情況,每一個我都列出來,本質(zhì)上是一個循環(huán).

  • 2022-2-1 + 12 _day = 13 < 2月份的最大值,返回 2022-2-13
  • 2022-4-30 + 7 _day = 37 > 4月份最大值, _day-=30 月份+1 = 5,我們發(fā)現(xiàn) _day = 7 < 5月份的最大值,循環(huán)結(jié)束
  • 2022-12-31 + 2 _day = 33 > 12月份最大值, _day-=31,月份是12,直接置為1, _year加1,繼續(xù)循環(huán),判斷 _day = 2是不是滿足循環(huán)條件
Date Date::operator+(const int day) const
{
  //先判斷  day 是否是 小于零
  if(day < 0)
  {
    return (*this)-(-day);
  }
  // 第一步  來個第三方 不要修改原來的
  Date ret(*this); // 這是拷貝構(gòu)造
  ret._day += day;
  while(ret._day > ret.isLegitimate(ret._year,ret._month))
  {
    ret._day -= ret.isLegitimate(ret._year,ret._month);
    
    if(ret._month == 12)
    {
      ret._month = 1;
      ret._year += 1;
    }
    else 
    {
      ret._month += 1;
    }
  }

  return ret;
}

重載+=

我們直接復用+和=就可以了,這里沒什么可以分享的.

Date& Date::operator+=(const int day)
{
  //判斷 是不是 小于 0
  if(day < 0)
  {
    return (*this) = (*this) - (-day);
  }
  return (*this) = (*this) + day;
}

重載 -

我們們這里要重載加號的的話,需要分為兩種共請情況

  • 參數(shù) 是 天數(shù)
  • 參數(shù) 是 日期

很榮幸,C++是支持重載的,我們也按照步驟來.

參數(shù)是天數(shù)

這個就是計算一個日期減去多少天得到另一個日期,也是比較簡單的,我們要考慮一些之情況,這里小于零的情況就不解釋了,主要看我們的思路是什么.

我們首先把_day減去day,判斷是不是小于0,小于的話,就從上個月的日期天數(shù)加到 _day上,直到它它大于0,這里要注意的是,如果我們的月份恰好是12,那么上一個月是1月份,并且年也要減1

Date Date::operator-(const int day) const
{
  // day 的大小 
  if(day < 0)
  {
    return (*this) + (-day);
  }
  Date ret(*this);
  ret._day -= day;

  //開始判斷  ret._day 
  while(ret._day <= 0)
  {
    // 找上一個月的
    if(ret._month == 1)
    {
      ret._month = 12;
      ret._year -= 1;
    }
    else 
    {
      ret._month -= 1;
    }
    int days = ret.isLegitimate(ret._year,ret._month);
    ret._day += days;
  }
  return ret;
} 

參數(shù)是日期

這個更加簡單的,我們計算的是兩個日期之間差的天數(shù),我們可以復用前面的方法.

還是先說下思路,我們想,如果一個較小的日期每次加一,直到加到和較大的日期完全一樣,我們計算加的次數(shù)是不是就可以完成這個操作符的重載了.那么我們?nèi)绾我玫礁〉娜掌?是不是要比較,然后交換這里是不用的,我們用一個標志位.我們假設日期A比日期B小,標志位flag = 1,如果不成立,我們把flag編程-1,隨即我們用日期A加上flag,進行循環(huán).

int Date:: operator-(const Date& d)
{
  // 給一個 數(shù)  來計數(shù)
  int count = 0;
  int flag = 1;
  // 不能修改原來的,這里用一個第三方
  Date ret(*this);
  if(ret > d)
  {
    flag = -1;
  }
  while(ret != d)
  {
    ret += flag;
    count++;
  }
  return flag*count;
  
}

重載-=

這個我們復用減號就可以了,就不解釋了.

Date& Date::operator-=(const int day)
{
  if(day < 0)
  {
    return(*this) = (*this)+(-day);
  }
  return (*this) = (*this) - day;
}

重載++

我們這就不解釋前置和后置的區(qū)別了,上一個博客分享過了,直接開始吧.

前置

前置是不需要帶參數(shù)的.

Date& Date::operator++()
{
  *this += 1;
  return *this;
}

后置

需要帶一個int類型的參數(shù)

Date Date::operator++(int day)
{
  Date ret(*this);
  *this += 1;
  return ret;
}

重載 –

既然我們都把減法給重載了,那這我們直接復用就可以了

前置

不帶參數(shù)

Date& Date::operator--()
{
  *this -= 1;
  return *this;
}

后置

帶上參數(shù)

Date Date:: operator--(int day)
{
  Date ret(*this);
  *this -= 1;
  return ret;
}

重載流提取 & 流插入

這原理我們已經(jīng)分享過了,這里就不加贅述了,記得使用友元

>>

std::istream& operator>>(std::istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

<<

std::ostream& operator<<(std::ostream& out, Date& d)
{
	out << d._year << "-" << d._month << "-" << d._day;
	return out;
}

到此這篇關(guān)于C++ Date類的具體使用(構(gòu)建,重載等)的文章就介紹到這了,更多相關(guān)C++ Date類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言如何改變字體顏色

    C語言如何改變字體顏色

    這篇文章主要介紹了C語言如何改變字體顏色,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Qt 鼠標/觸屏繪制平滑曲線(支持矢量/非矢量方式)

    Qt 鼠標/觸屏繪制平滑曲線(支持矢量/非矢量方式)

    這篇文章主要介紹了Qt 鼠標/觸屏繪制平滑曲線(支持矢量/非矢量方式),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • C語言?超詳細總結(jié)講解二叉樹的概念與使用

    C語言?超詳細總結(jié)講解二叉樹的概念與使用

    二叉樹可以簡單理解為對于一個節(jié)點來說,最多擁有一個上級節(jié)點,同時最多具備左右兩個下級節(jié)點的數(shù)據(jù)結(jié)構(gòu)。本文將詳細介紹一下C++中二叉樹的概念和結(jié)構(gòu),需要的可以參考一下
    2022-04-04
  • C++多重繼承引發(fā)的重復調(diào)用問題與解決方法

    C++多重繼承引發(fā)的重復調(diào)用問題與解決方法

    這篇文章主要介紹了C++多重繼承引發(fā)的重復調(diào)用問題與解決方法,結(jié)合具體實例形式分析了C++多重調(diào)用中的重復調(diào)用問題及相應的解決方法,需要的朋友可以參考下
    2018-05-05
  • 從C++單例模式到線程安全詳解

    從C++單例模式到線程安全詳解

    下面小編就為大家?guī)硪黄獜腃++單例模式到線程安全詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • 使用QT連接USB攝像頭的方法

    使用QT連接USB攝像頭的方法

    這篇文章主要為大家詳細介紹了使用QT連接USB攝像頭的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C++?多繼承詳情介紹

    C++?多繼承詳情介紹

    這篇文章主要介紹了C++?多繼承詳情,C++支持多繼承,即允許一個類同時繼承多個類。只有C++等少數(shù)語言支持多繼承,下面我們就來看看具體的多繼承介紹吧,需要的朋友可以參考一下
    2022-03-03
  • C++中訪問權(quán)限的示例詳解

    C++中訪問權(quán)限的示例詳解

    C++通過 public、protected、private 三個關(guān)鍵字來控制成員變量和成員函數(shù)的訪問權(quán)限(也稱為可見性),下面這篇文章主要給大家介紹了關(guān)于C++中訪問權(quán)限的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • C語言函數(shù)指針詳解

    C語言函數(shù)指針詳解

    本文主要介紹 C語言函數(shù)指針的知識,這里整理了詳細的資料及示例代碼以便大家學習參考,有需要學習此部分知識的朋友可以參考下
    2021-09-09
  • 如何通過C++求出鏈表中環(huán)的入口結(jié)點

    如何通過C++求出鏈表中環(huán)的入口結(jié)點

    本文主要介紹了通過C++求解鏈表中環(huán)的入口結(jié)點,即給一個長度為n鏈表,若其中包含環(huán),請找出該鏈表的環(huán)的入口結(jié)點,否則,返回null。需要的朋友可以參考一下
    2021-12-12

最新評論