类和对象(拷贝构造和运算符重载)下

类和对象(拷贝构造和运算符重载)下

这一集的主要目标先是接着上一集讲完日期类。然后再讲一些别的运算符的重载,和一些语法点。

这里我把这一集要用的代码先放出来:(大家拷一份代码放在编译器上先)

Date.h

#include <iostream>
#include <cassert>
using std::cout;
using std::cin;
using std::endl;
using std::ostream;
using std::istream;

class Date
{
private:
    int _year;
    int _month;
    int _day;
public:

    //构造函数
    Date(int year=2025,int month=4,int day=30);
    //拷贝构造函数//日期类可以不写拷贝构造函数,编译器写的符合我们的要求
    Date(const Date& dd);
    //析构函数就不写了,日期类并不需要

    //打印
    void Print();
    //获取当年当月的天数
    int monthday(int year,int month);

    //比较日期大小
    bool operator==(const Date& other);
    bool operator!=(const Date& other);
    bool operator>(const Date& other);
    bool operator<(const Date& other);
    bool operator>=(const Date& other);
    bool operator<=(const Date& other);

    //加减运算
    Date& operator+=(int day);//加上n天后的日期是多少
    Date operator+(int day);
    Date& operator-=(int day);//n天前的日期是多少
    Date operator-(int day);

    Date& operator++();//前置++
    Date operator++(int);//后置++
    Date& operator--();
    Date operator--(int);

    int operator-(const Date& other);//两个日期相隔几天

    //赋值重载
    Date& operator=(const Date& other);
    //流插入重载//声明为友元函数
    friend ostream& operator<<(ostream& out, const Date& dd);
    //流提取重载
    friend istream& operator>>(istream& in, Date& dd);

    //&取地址重载
    Date* operator&();
    //const取地址&重载
    const Date* operator&() const;
};

ostream& operator<<(ostream& out, const Date& dd);
istream& operator>>(istream& in, Date& dd);

Date.cpp

#include "Date.h"

Date::Date(int year,int month,int day)
{
    _year=year;
    _month=month;
    _day=day;

    if (_year < 1 ||
        _month < 1 || _month > 12 ||
        _day < 1 || _day > monthday(_year, _month))
    {
        //assert(false);
        Print();
        cout << "日期非法" << endl;
    }
}

Date::Date(const Date& dd)
{
    _year=dd._year;
    _month=dd._month;
    _day=dd._day;
}

void Date::Print()
{
    cout<<_year<<'_'<<_month<<'_'<< _day<<endl;
}

int Date::monthday(int year,int month)
{
    assert(year>=1 && month>=1 && month<=12);

    int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    if(month==2 && ((year%4==0 && year%100!=0) || year%400==0))
    {
        return 29;
    }
    else
    {
        return day[month];
    }
}


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

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

bool Date::operator>(const Date& other)
{
    if(_year>other._year)
    {
        return true;
    }
    if(_year==other._year && _month>other._month)
    {
        return true;
    }
    if(_year==other._year && _month==other._month && _day>other._day)
    {
        return true;
    }

    return false;
}

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

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


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

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

    Date tmp(*this);
    tmp+=day;

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

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

    return tmp;
}

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

    return *this;
}
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;
}

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

Date& Date::operator=(const Date& other)
{
    if(this != &other)//防止自己给自己赋值
    {
        _year=other._year;
        _month=other._month;
        _day=other._day;
    }
    return *this;
}

//流插入重载
ostream& operator<<(ostream& out, const Date& dd)
{
    out<<dd._year<<'_'<<dd._month<<'_'<<dd._day<<endl;

    return out;
}
//流提取重载
istream& operator>>(istream& in,Date& dd)
{
    in>>dd._year>>dd._month>>dd._day;

    return in;
}

//&取地址重载
Date* Date::operator&()
{
    return this;
}
//const取地址&重载
const Date* Date::operator&() const
{
    return this;
}

main.cpp

#include "Date.h"

void Test()
{
    Date d1;
    Date d2(1999,10,17);
    Date d3;
    int day=d1-d2;
    int day1=d3-d1;
    cout<<day<<endl<<day1<<endl;
}
void Test1()
{
    Date d1;
    cout<<d1<<endl;
    cin>>d1;
    cout<<d1<<endl;

}
int main()
{
    Test();

    return 0;
}

大家想去验证结果的时候可以去网上搜:日期计算器

在这里插入图片描述

我会按照头文件函数声明的顺序讲解函数逻辑,以及语法点:

日期类函数顺序讲解:

  • int monthday(int year,int month);
    

在这里插入图片描述

  • bool operator==(const Date& other);
    bool operator!=(const Date& other);
    

在这里插入图片描述

  • bool operator>(const Date& other);
    bool operator<(const Date& other);
    bool operator>=(const Date& other);
    bool operator<=(const Date& other);
    

在这里插入图片描述

  • Date& operator+=(int day);//加上n天后的日期是多少
    Date operator+(int day);
    Date& operator-=(int day);//n天前的日期是多少
    Date operator-(int day);
    

在这里插入图片描述
在这里插入图片描述

  • Date& operator++();//前置++
    Date operator++(int);//后置++
    Date& operator--();
    Date operator--(int);
    

在这里插入图片描述

  • int operator-(const Date& other);//两个日期相隔几天
    

在这里插入图片描述

  • //赋值重载
    Date& operator=(const Date& other);
    

这个上一集有讲, 这一集就不讲了。

那么到这里为止, 日期类的一些基础逻辑函数都已经讲完了, 现在来填一下前面埋的坑.

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

好, 这部分的坑填完了, 接着讲一些别的重载:

  • //流插入重载//声明为友元函数
    friend ostream& operator<<(ostream& out, const Date& dd);
    //流提取重载
    friend istream& operator>>(istream& in, Date& dd);
    

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

有的同学觉得, 诶, 这不会和位移运算符<<这些冲突嘛? 不会的, 编译器没那么傻. 而且能用位移运算符的不也就整型嘛. 所以不会有问题的.

  • const成员函数

在 C++ 里,const成员函数是一种特殊的成员函数,它的关键作用在于保证该函数不会对调用它的对象的成员变量进行修改。(一句话就是: 只要是你不修改对象本身的函数, 你都给我加上const)

定义与语法

在成员函数的参数列表之后添加const关键字,就能将其声明为const成员函数。其基本语法如下:

class ClassName {
public:
    // 返回类型 函数名(参数列表) const
    ReturnType functionName(ParameterList) const {
        // 函数体
    }
};

注意事项

  • this指针:在const成员函数内部,this指针是一个指向const对象的指针,这就保证了函数内部不能通过this指针来修改对象的成员变量。
  • 函数重载const成员函数可以和非const成员函数进行重载。当调用成员函数时,编译器会依据对象是否为const来选择合适的函数。(注意昂, 就要用到这一点了)

在这里插入图片描述

这里const成员函数其实有一个权限问题, 说白了就是const修饰之后不就是多了一道枷锁嘛. 你不能说我给你带上了锁, 你还给我解开跑了, 这是不行的.

权限只能平移或缩小, 不能放大. 这就像市长可以可以管理市内业务(平移), 也可以管理一个村子(缩小), 但是你没有权限去管省长干的事情. (大概是这个意思, 不严谨的举例哈)

  • //&取地址重载
    Date* operator&();
    //const取地址&重载
    const Date* operator&() const;
    

在这里插入图片描述

  • 函数重载const成员函数可以和非const成员函数进行重载。当调用成员函数时,编译器会依据对象是否为const来选择合适的函数。看到没.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值