<>前面声明
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函数。