类与对象(中)

一、获取私有成员的三种方法

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修饰的意义

 

一些特殊用法,如不想他人取地址时,可以自己重载一个取地址符号函数

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值