Data类
声明和定义分离的一些问题
声明里面我们不带缺省参数,定义我们给缺省参数,如下面两段代码:
Data.h#pragma once
#include<iostream>
using namespace std;
class Data
{
public:Data(int year,int month,int day);private:int _year;int _month;int _day;};
Data.cpp#include"Data.h"Data::Data(int year=1 , int month=1 , int day=1 ){_year = year;_month = month;_day = day;}
现在我们在main函数调用:
d1没报错,d2报错了:
这是因为我们main函数那个文件包的是.h文件,声明我们没有给缺省参数,声明就好比一种承诺,
没给参数,我们d2没有默认参数就过不了。
我们给个默认参数看看:
#pragma once
#include<iostream>
using namespace std;
class Data
{
public:Data(int year = 1, int month = 1, int day = 1);
private:int _year;int _month;int _day;};
声明和定义不能同时给默认参数,我们把定义的默认参数去了就可以了。
OK,我们写个print函数就可以把日期打印出来看看了:
Data.cppvoid Data:: print(){cout << _year << "年" << _month << "月" << _day << "日" << endl;}
我们发现上面这段日期是有问题的,有点的是闰年,有的是13月,是一些不合法日期,所以我们要加日期有效判断。
日期判断
引用上一篇文章写的:
int Getmonth(int year,int month){int GetArry[13] = {0, 31,28,30,31,30,31,30,31,30,31,30,31 };if (month==2&&(month % 4 == 0 && month % 10 == 0 || month % 400 != 0)){return 29;}return GetArry[month];}
可以在Getmonth函数前面加一个static,因为Getmonth肯定会被频繁调用,每一次都进来会造成消耗,所以用static让它具有全局属性。
然后我们给输入的日期加判断:
拷贝构造
日期类需不需要我们自己写拷贝构造,不需要,因为日期类就三个成员变量:int _year ,int _month,int _day,全是内置类型,编译器会自动生成拷贝构造:
Data d1(2003,11,33);d1.print();Data d2(d1);d2.print();
赋值运算符重载
如下,d1的日期为非法日期,d3为合法日期,我把d3的日期赋值给d1,让d1也成为合法日期:
Data d1(2003,11,33);
Data d3(2003,11,30);d1 = d3;d3.print();d1.print();
但是两个类之家是不能之间进行赋值的,这个可以运行是因为编译器默认生成了运算符重载,将d3的成员变量的值逐个复制给d1的成员变量。需要注意的是,当类中存在指针类型的成员变量时,使用默认的赋值运算符重载函数可能会导致浅拷贝问题。在这种情况下,你需要自己编写赋值运算符重载函数,以确保进行深拷贝操作,避免出现内存错误。
我们自己可以写一下赋值运算符重载:
赋值运算符重载和拷贝构造区别
内置类型我们可以像这样进行赋值:它的原理实际上是这样:
注意:优先级问题,还需要再加个括号:
但是自定义类型就不可以了:
那我们可以按照内置类型的思路:先让d4复制给d3,再返回一个值,把这个值再赋值给d1.
返回的这个值也要是Data类型,因为要返回一个日期,把这个日期再赋值给d1.
Data& Data::operator=(const Data& d3)
{this->_year = d3._year;this->_month = d3._month;this->_day = d3._day;return *this;
}
Data d1(2003, 11, 33);Data d3(2003, 11, 22);Data d4(2000, 12, 3);d1 = d3 = d4;d1.print();d3.print();d4.print();
解析: