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

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

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

寫在前面

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

成果

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

image-20220706150104866

準(zhǔn)備工作

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

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ù)

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

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

我們分別用方法來(lái)完成自己的要求.

判斷平年 or 閏年

這個(gè)很簡(jiǎn)單,記得去類里面聲明這個(gè)方法.

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];  
}

我來(lái)解釋一下我們定義數(shù)組的時(shí)候?yàn)槭裁从玫氖?static ? 我們知道,這是一個(gè)函數(shù),也就是說(shuō)函數(shù)棧幀會(huì)在結(jié)束后銷毀,但是我們可能多次調(diào)用這個(gè)函數(shù),為了避免多次開辟和銷毀該數(shù)組的空間,這里直接用static修飾得了.

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

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

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 
    {
        // 這里應(yīng)該拋出一個(gè)異常 
        // 現(xiàn)在我還不太會(huì) 暫時(shí)用 assert代替
        assert(NULL);
    }
}

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

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

由于這兩個(gè)函數(shù)都不大,這里就聲明成內(nèi)聯(lián)函數(shù)函數(shù)吧,在類內(nèi)實(shí)現(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;
}

運(yùn)算符重載

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

邏輯運(yùn)算符的重載

這個(gè)基本的邏輯運(yùn)算符都有意義,這里我們一一給大家重載出來(lái),同時(shí)也驗(yàn)證一下.

重載 ==

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

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

image-20220706164559795

重載 >

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

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

重載 >=

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

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

image-20220706170227802

重載 <

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

我們知道,小于的對(duì)立面就是大于大于等于

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

重載 <=

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

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

重載 !=

這個(gè)更加簡(jiǎn)單,不等于不就是等于的對(duì)立面嗎

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

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

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

重載 =

等于的重載基本來(lái)說(shuō)對(duì)于我們是沒有任何問(wèn)題的,但是有一點(diǎn)是需要我們注意的,無(wú)論是C語(yǔ)言還是C++都是支持連等的,也就是a = b = c,那就意味者我們們重載等于的時(shí)候是要有返回值的.

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

重載 +

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

那么我們?cè)撊绾伟堰@個(gè)邏輯給完善好呢?第一步,就是把給的天數(shù)直接加到_day上面,如果還沒有超過(guò)當(dāng)前月最大的天數(shù),我們就直接返回這個(gè)日期就可以了,否則就把日期減去當(dāng)前月最大的天數(shù),當(dāng)前月加一,注意,這里要明白,如果當(dāng)前月是12月,我們直接把月份置為1,年加上一,這里要注意一點(diǎn)東西 ,我們不修改原來(lái)的日期

我們可以分為三種情況,每一個(gè)我都列出來(lái),本質(zhì)上是一個(gè)循環(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);
  }
  // 第一步  來(lái)個(gè)第三方 不要修改原來(lái)的
  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;
}

重載+=

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

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

重載 -

我們們這里要重載加號(hào)的的話,需要分為兩種共請(qǐng)情況

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

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

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

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

我們首先把_day減去day,判斷是不是小于0,小于的話,就從上個(gè)月的日期天數(shù)加到 _day上,直到它它大于0,這里要注意的是,如果我們的月份恰好是12,那么上一個(gè)月是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)
  {
    // 找上一個(gè)月的
    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ù)是日期

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

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

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

重載-=

這個(gè)我們復(fù)用減號(hào)就可以了,就不解釋了.

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

重載++

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

前置

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

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

后置

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

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

重載 –

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

前置

不帶參數(shù)

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

后置

帶上參數(shù)

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

重載流提取 & 流插入

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

>>

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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言如何改變字體顏色

    C語(yǔ)言如何改變字體顏色

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

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

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

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

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

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

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

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

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

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

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

    C++?多繼承詳情介紹

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

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

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

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

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

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

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

最新評(píng)論