植物大战 日期类——C++

时间:2023-01-02 18:51:14

前面声明

2023_01_01.
虽然详解的是日期类。但实际不是日期类。而是C++特性的实际操作使用。算是实操。

头文件的讲解

**注意一下private里面的变量是声明出来的。不占内存。只有实例化出来的对象里面才有private里面的数据。**声明和定义的区别需要分开。
头文件std的内容一般不需要全部都打开,只需要把cout和cin放出来就行。
稍微正式的地方不需要展开,但是一个大项目为了规范不能直接使用using namespace std;

日期类的讲解

对于日期类来说,运算符重载才是重点。
对于声明和定义分离来说。我们需要指定函数的类域。注意类域在返回类型的后面

运算符重载如果能复用就复用,比如大于小于的运算符重载。

拷贝构造函数

**注意:拷贝构造是用一个对象创建一个不存在的对象。**赋值是用两个存在的对象相互赋值。

因为日期类不需要深拷贝,浅拷贝就能完成值拷贝,所以默认构造函数就可以完成值拷贝。因为对内置类型完成值拷贝。完成值拷贝对日期类来说已经足够了。

重载<=

复用小于 和 等于的函数即可。

return *this < d || *this == d;

因为流插入的运算符优先级非常高。所以需要加括号指定优先级。

cout << (d1 <= d2);

内联函数

对于特别短的函数可以搞成内联函数。
内联函数就是在函数前面加上 inline。
内联函数不能声明和定义分别放到两个文件中。**为什么呢?因为函数调用时找不到inline函数的地址。只能找到声明,所以编译不会报错,链接会报错,因为它是直接展开的。**所以成员函数中要成为inline最好直接放在类里面定义。
在类里面直接定义函数默认就是内联函数

判断是不是闰年

顺口溜就是:四年一润,百年不润,或者 四百年润一次

if((year % 4 ==0 && year % 100 != 0)
||(year % 400 == 0))

重载流插入运算符<<

得到当前月的天数

直接用一个数组标记每个月的天数,然后返回数组需要的元素即可。

这个数组可以用static修饰。因为这个函数需要频繁调用,所以需要每次都要开辟这个数组。直接把数组放静态区,每次都是用的这一个数组。

多个线程读数据是没问题的,但是写可能是有问题的。

重载+运算符

注意+不是+=。自身不变,所以需要先拷贝一个对象。来作为返回的对象。

返回的对象因为是临时构造出来的。出了作用域就会销毁掉。所以不能返回引用。

天满进月,月满进年。

关于形参引用的问题

一般形参加了引用,如果不改变形参,就加上const。
好处一:可以防止误写
好处二:可以防止传入临时对象。即cosnt的对象。导致权限放大。
一般const修饰的叫做右值。const只有读的权限。

Date(const Date& d)

关于C++的引用返回

学了C++的这些特性就要用起来。
一般能用引用返回的就用引用返回,能减少普通返回就减少。因为普通返回会导致拷贝构造。

注意:**传值返回一定是正确的,但不一定是高效的,**只要对象不销毁就用传值返回。

重载减法

1.对于减法,需要注意边界,首先日期没有0号。都是从1号开始。
2.对于天数,**如果天小于等于0就要借位,借的话这里需要注意借的是上个月的天数。**而不是当前月。

重载++

这里有个坑的地方就是前置++和后置++怎么写。
C++为了区分前置和后置。则在后置的形参加一个int类型做占位符即可。
注意形参是可以不写的。只用写类型来代表不接收传过来的实参。
语法规定,前置++无形参。
调用的时候后置++用如下代码

d.operator(1);//传什么都无所谓。

但实际代码这个调用编译器帮我们做了。

关于前置++

Date& operator++()
{
	*this += 1;
	return *this;
}

关于后置++

Date operator++(int)
{
	Date re(*this);
	*this += 1;
	return ret;
}

关于没有形参的函数是否要给形参加const

没有形参的函数的const需要加在函数的后面加上const。如果需要的话。

只要不改变对象的值。还有对象的变量的值,都可以加上const。比如printf函数。