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.cpp
void 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();
解析: