Open bosthhe1 opened 1 year ago
#include<iostream>
using namespace std;
class DATE
{
public:
DATE(int year = 1970,int monsh = 1,int day = 1)
{
_year = year;
_monsh = monsh;
_day = day;
}
DATE(DATE &d)
{
_year = d._year;
_monsh = d._monsh;
_day = d._day;
}
DATE& operator=(const DATE &d);
bool operator!=(const DATE &d)const;
bool operator>(const DATE &d)const;
bool operator==(const DATE &d)const;
bool operator>=(const DATE &d)const;
bool operator<=(const DATE &d)const;
bool operator<(const DATE &d)const;
int GetMonshDay(int year, int monsh);
friend ostream& operator<<( ostream &cout,const DATE& d);
friend istream& operator>>(istream &cin,DATE& d);
int operator-(DATE& d);
DATE& operator++();
DATE operator+(int day);
void Print() const;
private:
int _year =10;
int _monsh=20;
int _day;
};
DATE DATE::operator+(int day)
{
DATE tmp(*this);
tmp._day+=day;
while(tmp._day > GetMonshDay(tmp._year,tmp. _monsh))
{
tmp._day -= GetMonshDay(tmp._year,tmp._monsh);
tmp._monsh++;
if (tmp._monsh > 12)
{
tmp._year++;
tmp._monsh = 1;
}
}
return tmp;
}
bool DATE::operator!=(const DATE &d)const
{
if (_year != d._year)
return false;
if (_year == d._year&&_monsh != d._monsh)
return false;
if (_year == d._year&&_monsh == d._monsh&&_day != d._day)
return false;
return true;
}
DATE& DATE::operator++()
{
_day++;
if (_day++ > GetMonshDay(_year, _monsh))
{
_day -= GetMonshDay(_year, _monsh);
_monsh++;
if (_monsh > 12)
{
_year++;
_monsh = 1;
}
}
return *this;
}
int DATE::operator-(DATE& d)
{
int flag = 1;
DATE min = (*this);
DATE max = d;
if (max > min)
{
flag = 1;
}
else
{
max = (*this);
min = d;
flag = -1;
}
int day = 0;
while ((min+day) < max)
{
day++;
}
return day*flag;
}
istream& operator>>(istream &cin,DATE& d)
{
cin >> d._year >>d._monsh >>d._day;
return cin;
}
ostream& operator<<(ostream &cout,const DATE& d)
{
cout << d._year << "-" << d._monsh << "-" << d._day<<endl ;
return cout;
}
void DATE::Print()const
{
cout << _year << "-" << _monsh << "-" << _day << endl;
}
bool DATE::operator==(const DATE &d)const
{
if (_year == d._year&&_monsh == d._monsh&&_day == d._day)
{
return true;
}
return false;
}
int DATE::GetMonshDay(int year,int monsh)
{
int GetMonshArr[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
{
GetMonshArr[2]++;
}
return GetMonshArr[monsh];
}
bool DATE::operator>(const DATE &d)const
{
if (_year > d._year)
{
return true;
}
if (_year == d._year&&_monsh > d._monsh)
{
return true;
}
if (_year == d._year&&_monsh == d._monsh&&_day > d._day)
{
return true;
}
return false;
}
bool DATE::operator>=(const DATE &d)const
{
if (*this > d || *this == d)
{
return true;
}
return false;
}
bool DATE::operator<(const DATE &d)const
{
if (!(*this>d))
return true;
return false;
}
bool DATE::operator<=(const DATE &d)const
{
if (*this < d || *this == d)
{
return true;
}
return false;
}
DATE& DATE::operator=(const DATE &d)
{
_year = d._year;
_monsh = d._monsh;
_day = d._day;
return *this;
}
int main()
{
DATE d1;
DATE d2(1998,12,03);
cout << ++d1 << ++d2;
//cin >> d2 >> d1;
//cout << d2;
//cout << d1;
//cout << (d1 - d2) << endl;
//cout << (d2 > d1) << endl;
//cout << (d2 <= d1) << endl;
DATE const d3;
d3.Print();
return 0;
}
初始化列表的注意事项
上面的初始化列表按照顺序走的话,是先将1给了_a1赋值,然后将_a1给_a2赋值,这样打印出来a1和a2都是1,但是实际上却不是这个逻辑 我们看到a1是1,但是a2是随机值,因为初始化列表初始化的顺序是按照成员声明的顺序走的,我们先声明了a2,然后再声明了a1,所以初始化列表会先初始化a2,再初始化a1,a2的初始化是靠a1的值,但是a1还未被初始化,所以是随机值,那么我们看到的a2打印出来就是随机值,而a1不受影响
需要注意的是,我们对于const函数和普通函数调用是不一样的,const的函数调用,是需要调用对象的本身是const才可以调用,而普通函数则没有影响,函数调用和接受值无关,编译器不会用这里的iterator去推到调用的函数,而是用对象本身是否拥有const属性来调用具体函数 类型匹配(会去调用最匹配的问题): 普通对象,如果存在普通的函数和const函数,就会去调用普通函数(权限不变),如果没有普通函数,只有const函数,就去调用const的函数(权限缩小),但是对于const对象,就只能调用const的函数,不能调用普通函数,如果没有const函数会报错 我们看到在函数调用的时候,都是调用的begin(),但是it是调用的普通函数,it2是调用const修饰的函数
需要注意的是,前置++和后置++,编译器为了区分前置++和后置++,将后置++进行运算符重载,使用了占位参数,这个占位参数类型必须是int DATE operator++();前置++ DATE operator++(int);后置++,占位参数必须是int
赋值运算符只能重载成成员函数,在类中不显式实现时,编译器会生成一份默认的,此时用户在类外再将赋值运算符重载为全局的,就和编译器生成的默认赋值运算符冲突了,故赋值运算符只能重载成成员函数
赋值符重载听起来好像是对符号重新定义一个功能,但是本质还是不变,是对已经存在的变量,进行赋值,假如a,b变量已经存在,a = b就是对a变量的赋值,在我们常规的理解中a可能是int类型,或者char类型,不可能对类进行赋值相等,赋值符重载就是为了解决这个问题,让两个类里面的成员也能相等, 这里就需要用到函数operator 首先这里的赋值的类型视情况而定,图片里面是赋值的类的类型,所以返回类型是类,然后这里的返回值可以传引用也可以不传引用,因为传引用返回可以减少拷贝,但是有可能出了作用域参数就销毁了,所以需要确保参数不被销毁,才可以传引用。 这里的参数类型可以传引用,减少调用拷贝消耗,但是传引用有一个不安全的点,就是传了引用过来,引用就是实参的别名,我们改变函数的参数,就改变了外面的实参,所以我们一般在前面会加一个const 同样我们这里会有一个this指针 注意我们需要将赋值符重载和拷贝构造函数区分开 赋值符重载是将两个已经存在的变量,进行操作 拷贝构造函数重载是将一个已经存在的变量,去初始化另外一个未初始化的变量