日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

基于C++實現一個日期計算器_C 語言

作者:蔣靈瑜的筆記本 ? 更新時間: 2022-11-21 編程語言

一、日期計算器的功能

實現日期類的==、!=、+=、+、-=、-、>=、>、<=、<、前置++和--、后置++和--。

二、獲取每個月的天數

int GetMonthDay(int year, int month)
{
    //靜態數組,每次調用不用頻繁在棧區創建數組
    static int monthArr[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
    //判斷是否閏年
    int day = monthArr[month - 1];
    if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
    {
        day = 29;
    }
    return day;
}

1、因為GetMonthDay這個函數需要在日期類中被頻繁調用,所以將 monthArr存放至靜態區,減少數組頻繁開辟、銷毀空間的開銷。

三、Date類中的默認成員函數

1、構造函數

Date(int year = 1, int month = 1, int day = 1)
{
    if (year >= 1 && month >= 1 && day >= 1 && day <= GetMonthDay(year, month))
    {
        _year = year;
        _month = month;
        _day = day;
        //cout << "構造成功" << endl;
    }
    else
    {
        cout << "日期不合法" << endl;
    }
}

日期類的構造函數需要對日期的的合法性進行判斷。

2、析構函數

~Date()//可不寫
{
    ;
}

日期類因為沒有申請資源(動態開辟空間、文件的打開等),所以無需寫析構函數,系統默認生成的就可以。

3、拷貝構造

Date(const Date& d)//可不寫
{
    _year = d._year;
    _month = d._month;
    _day = d._day;
    //cout << "拷貝構造成功" << endl;
}

系統默認生成的拷貝構造函數會對內置類型完成淺拷貝,所以內置類型也可以不用寫,用系統默認生成的就可以。

4、賦值運算符重載

Date& operator=(Date& d)
{
    _year = d._year;
    _month = d._month;
    _day = d._day;
    //cout << "賦值成功" << endl;
    return *this;
}

也可不寫,使用系統默認生成的即可。

拷貝構造和賦值運算符重載的區別在于拷貝構造用于對象構造時使用,而賦值運算符重載用于已存在對象賦值時使用。

四、運算符重載

1、+=、+、-=、-

Date& operator+=(int day)
{
    if (day < 0)
        *this -= -day;
    else
    {
        _day += day;
        while (_day > GetMonthDay(_year, _month))
        {
            _day -= GetMonthDay(_year, _month);
            ++_month;
            if (_month > 12)
            {
                _month = 1;
                ++_year;
            }
        }
    }
    return *this;
}
Date operator+(int day)
{
    Date tmp(*this);
    return tmp += day;
}
Date& operator-=(int day)
{
    if (day < 0)
        *this += -day;
    else
    {
        _day -= day;
        while (_day <= 0)
        {
            --_month;
            if (_month <= 0)
            {
                _month = 12;
                --_year;
            }
            _day += GetMonthDay(_year, _month);
        }
    }
    return *this;
}
Date operator-(int day)
{
    Date tmp(*this);
    return tmp -= day;
}
//日期減日期
int operator-(const Date& d)
{
    Date tmpThis = *this, tmpDay = d;
    int count = 0;//用于計數
    if (*this >= d)
    {
        while (tmpDay != tmpThis)
        {
            ++tmpDay;
            ++count;
        }
    }
    else
    {
        while (tmpDay != tmpThis)
        {
            ++tmpThis;
            --count;
        }
    }
    return count;
}

1、注意這幾個運算符要防止外部傳入的day是負數。例如+=傳入的參數如果是負數,則去調用-=函數。

2、注意傳值返回和傳引用返回,當return對象出了作用域還存在時,可以用傳引用返回,減少一次拷貝構造。

3、實現完+=、-=后,+、-運算符可復用邏輯。

2、==、!=、>、>=、<、<=

bool operator==(const Date& d)
    {
        if (_year == d._year && _month == d._month && _day == d._day)
        {
            return true;
        }
        return false;
    }
    bool operator>(const Date& d)
    {
        if (_year > d._year)
            return true;
        if (_year == d._year && _month > d._month)
            return true;
        if (_year == d._year && _month == d._month && _day > d._day)
            return true;
        return false;
    }
    bool operator>=(const Date& d)
    {
        return *this > d || *this == d;
    }
    bool operator!=(const Date& d)
    {
        return !(*this == d);
    }
    bool operator<(const Date& d)
    {
        return !(*this >= d);
    }
    bool operator<=(const Date& d)
    {
        return !(*this > d);
    }

1、注意右操組數一定要加上&,減少一次傳參時的拷貝構造;再加上const,防止被引用的對象被改變。

2、寫完==和>函數,其他運算符都可以復用邏輯。

3、前置++和--、后置++和--

Date& operator++()
    {
        ++_day;
        if (_day > GetMonthDay(_year, _month))
        {
            _day = 1;
            ++_month;
            if (_month > 12)
            {
                _month = 1;
                ++_year;
            }
        }
        return *this;
    }
    Date operator++(int)
    {
        Date tmp(*this);
        ++* this;
        return tmp;
    }
    Date& operator--()
    {
        --_day;
        if (_day <= 0)
        {
            --_month;
            if (_month == 0)
            {
                _month = 12;
                --_year;
            }
            _day += GetMonthDay(_year, _month);
        }
        return *this;
    }
    Date operator--(int)
    {
        Date tmp(*this);
        --* this;
        return tmp;
    }

1、因為++和--是單操作數的運算符,在重載時,無法區分是前置的重載還是后置的重載,所以C++規定:前置重載與普通運算符重載一致,后置重載需要在參數列表中加入一個無用的參數。這個參數必須是int類型(用別的類型編譯器報錯)。

2、前置++--可以使用傳引用返回,但后置++--因為返回值暫時不改變,所以只能傳值返回。這也是使用前置++--性能優于后置++--的原因。

五、日期類代碼

class Date
{
public:
    void Print()
    {
        cout << _year << " " << _month << " " << _day << endl;
    }
    int GetMonthDay(int year, int month)
    {
        //靜態數組,每次調用不用頻繁在棧區創建數組
        static int monthArr[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
        //判斷是否閏年
        int day = monthArr[month - 1];
        if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
        {
            day = 29;
        }
        return day;
    }
    //構造函數
    Date(int year = 1, int month = 1, int day = 1)
    {
        if (year >= 1 && month >= 1 && day >= 1 && day <= GetMonthDay(year, month))
        {
            _year = year;
            _month = month;
            _day = day;
            //cout << "構造成功" << endl;
        }
        else
        {
            cout << "日期不合法" << endl;
        }
    }
    //析構函數
    ~Date()
    {
        cout << "析構成功" << endl;;
    }
    //拷貝構造
    Date(const Date& d)
    {
        _year = d._year;
        _month = d._month;
        _day = d._day;
        cout << "拷貝構造成功" << endl;
    }
    ////賦值運算符重載
    Date& operator=(Date& d)
    {
        _year = d._year;
        _month = d._month;
        _day = d._day;
        cout << "賦值成功" << endl;
        return *this;
    }
    //運算符重載
    Date& operator+=(int day)
    {
        if (day < 0)
            *this -= -day;
        else
        {
            _day += day;
            while (_day > GetMonthDay(_year, _month))
            {
                _day -= GetMonthDay(_year, _month);
                ++_month;
                if (_month > 12)
                {
                    _month = 1;
                    ++_year;
                }
            }
        }
        return *this;
    }
    Date operator+(int day)
    {
        Date tmp(*this);
        return tmp += day;
    }
    Date& operator-=(int day)
    {
        if (day < 0)
            *this += -day;
        else
        {
            _day -= day;
            while (_day <= 0)
            {
                --_month;
                if (_month <= 0)
                {
                    _month = 12;
                    --_year;
                }
                _day += GetMonthDay(_year, _month);
            }
        }
        return *this;
    }
    Date operator-(int day)
    {
        Date tmp(*this);
        return tmp -= day;
    }
    int operator-(const Date& d)
    {
        Date tmpThis = *this, tmpDay = d;
        int count = 0;//用于計數
        if (*this >= d)
        {
            while (tmpDay != tmpThis)
            {
                ++tmpDay;
                ++count;
            }
        }
        else
        {
            while (tmpDay != tmpThis)
            {
                ++tmpThis;
                --count;
            }
        }
        return count;
    }
    bool operator==(const Date& d)
    {
        if (_year == d._year && _month == d._month && _day == d._day)
        {
            return true;
        }
        return false;
    }
    bool operator>(const Date& d)
    {
        if (_year > d._year)
            return true;
        if (_year == d._year && _month > d._month)
            return true;
        if (_year == d._year && _month == d._month && _day > d._day)
            return true;
        return false;
    }
    bool operator>=(const Date& d)
    {
        return *this > d || *this == d;
    }
    bool operator!=(const Date& d)
    {
        return !(*this == d);
    }
    bool operator<(const Date& d)
    {
        return !(*this >= d);
    }
    bool operator<=(const Date& d)
    {
        return !(*this > d);
    }
    Date& operator++()
    {
        ++_day;
        if (_day > GetMonthDay(_year, _month))
        {
            _day = 1;
            ++_month;
            if (_month > 12)
            {
                _month = 1;
                ++_year;
            }
        }
        return *this;
    }
    Date operator++(int)
    {
        Date tmp(*this);
        ++* this;
        return tmp;
    }
    Date& operator--()
    {
        --_day;
        if (_day <= 0)
        {
            --_month;
            if (_month == 0)
            {
                _month = 12;
                --_year;
            }
            _day += GetMonthDay(_year, _month);
        }
        return *this;
    }
    Date operator--(int)
    {
        Date tmp(*this);
        --* this;
        return tmp;
    }
private:
    int _year;
    int _month;
    int _day;
};

因為函數的聲明和定義全部放在類中,會被編譯器當成內聯函數處理。所以可以根據自身需要,將部分調用不頻繁、稍長的函數的聲明寫在類中,而定義寫在類外。

原文鏈接:https://blog.csdn.net/gfdxx/article/details/127235127

欄目分類
最近更新