一、获取私有成员的三种方法
1.声明公有的获取函数,如:getYear()
2.友元函数
3.全局operator写在类里面
二、实现日期加天数 返回日期
1.时间戳
2.进位算法
例子1 2023.3.10 + 20天
10+20=30 ->合法 所以 2023.3.30
例子2 2023.3.10 + 30天
10+30=40 ->不合法 减去3月的天数,40-31=9,余9天,同时月份进一。即2023.4.9
其中每个月份的天数写一个函数来获取,可用静态数组打表记录,2月份特殊判断。
年份同理
三、实现日期类操作符比较
日期a是否大于b
if (a.年>b.年 或者 a.年==b.年&&a月>b月 或者a.年==b.年&&a月==b月&&a日>b日)
返回真
else
返回假
*引用返回
四、实现日期减去天数得到日期及2日期作差计算间隔天数
//四、实现日期减去天数得到日期
// 及2日期作差计算间隔天数
Date operator-(int d)
{
}
int operator-(Date d)
{
int flag = 1;
Date max = *this;
Date min = d;
//确定较大日期跟较小日期,flag设置为负数
if (min > max)
{
min = *this;
max = d;
flag = -1;
}
//用计数变量n 计数:较小的日期每次加1直到跟max较大的日期相等
int n = 0;
while (min != max)
{
min++;
n++;
}
return n * flag;
}
五、cout << 本质上就是运算符重载
"cout << XX " 相当于 "cout.operator<<()"
这是因为ostream 内置了运算符重载
现在希望可以cout<<Date 直接打印日期类
我们可以通过 重载全局运算符
失败方法:
类{
//五、直接cout Date对象
//①
//void operator<<(ostream& out) //前面隐藏了一个参数this,这种写法结果是 d1<<cout ,不是我们想要的
//{
// out << _year << ':' << _month << ':' << _day << endl;
//}
}
成功方法:(全局)
//五、全局 (改成全局的原因:写在类里面,会自带带上this
//占住了第一个位置变成了Date<<cout)
void operator<<(ostream& out, const Date& d) //我们希望的是cout在<<前,即参数顺序应为:out、Date。
{
out <<d._year << ':' << d._month << ':' << d._day << endl;
//此处不可访问私有:1.get函数获取 2.写成成员函数 3.友元:在类里面声明此全局函数是友元的,可以访问私有
}
此时year等私有成员是不可访问的,应该在类开头声明
friend void operator<<(ostream& out, const Date& d);
测试
输出符合预想
六、如何实现流插入拼接呢:cout<<d1<<d2
我们写的函数是空返回,所以直接输出是不理想的。
这里只需要把流out返回过去,就能实现右往左传递。
记得把友元函数的返回值类型也改了
结果
因为cout<<XXX 会频繁的调用,我们可以用内敛函数调高效率。
有了流插入,自然有流提取
流提取
代码
//六、输入日期
inline istream& operator>>(istream& in, Date& d) //我们希望的是cout在<<前,即参数顺序应为:out、Date。
{
in >> d._year >> d._month >> d._day;
//此处不可访问私有:1.get函数获取 2.写成成员函数 3.友元:在类里面声明此全局函数是友元的,可以访问私有
return in;
}
同样类里面需要声明友元
测试
运行结果
注意
不能通过连接其他符号来创建新的操作符:比如operator@
重载操作符必须有一个类类型参数
用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
* :: sizeof ?:
注意以上5个运算符不能重载。
还有一些其他的问题,见下文
七、const成员
见下方,这样编写会出现报错,为什么呢?
让我们看看 函数的定义
此处实际形参为(Date* const this,const Date& d)
对应的运算就是 :Date 类 > const Date类
而上面的 d3>d1 ,则是const Date 类 > Date类
编译识别不了,所以报错 const不能传给Date(权限放大) ;Date可以传给const (权限缩小)
方法
bool operator>(const Date& d)const
函数后面加个const,此时形参里的Date&const this 变成了 const Date& const* this
结果
编译不再报错
解释
d1到函数是:可读可写变成只读,属于权限缩小。
d2到函数是:只读变成只读,属于权限平移。
上述两种情况都没问题,而前面出现的问题是:
原d2到函数:只读变成可读可写(Date* const this) ,属于权限放大,这是错误的。
加const修饰的意义
一些特殊用法,如不想他人取地址时,可以自己重载一个取地址符号函数