【C++初阶】五、类和对象(日期类的完善、流运算符重载函数、const成员、“&”取地址运算符重载)

03-09 1158阅读

=========================================================================

相关代码gitee自取:

C语言学习日记: 加油努力 (gitee.com)

 =========================================================================

接上期:

【C++初阶】四、类和对象

(构造函数、析构函数、拷贝构造函数、赋值运算符重载函数)-CSDN博客

 =========================================================================

                     

一 . 日期类的完善

此次日期类的成员函数,采用声明和定义(实现)分离的方式实现

成员函数声明和定义(实现)分离的好处:

将成员函数的声明写在头文件中,方便我们查看这个类中有哪些成员函数,

其具体实现再到成员函数实现文件(.cpp文件)中查看

                        

(详细解释在图片的注释中,代码分文件放下一标题处)

                           

Date构造函数 -- 全缺省构造函数优化

                 

  • 当实例化对象时,所给的初始化参数可能不合理(比如给了负数的日期),
    需要进行特殊处理(报错)

                   

  • 注意:
    全缺省构造函数的缺省参数只能在声明或实现中给,
    不能两边都给缺省参数,不然编译器不知道要使用哪边的缺省参数,
    而且两边的缺省参数给得还可能不一样,
    所以这里选择在声明中给缺省参数,实现时并没有给
    图示:

    【C++初阶】五、类和对象(日期类的完善、流运算符重载函数、const成员、“&”取地址运算符重载)

    测试:

    【C++初阶】五、类和对象(日期类的完善、流运算符重载函数、const成员、“&”取地址运算符重载)

                              

                              

    ---------------------------------------------------------------------------------------------

                           

    Print函数 -- 打印日期函数

    图示:

    【C++初阶】五、类和对象(日期类的完善、流运算符重载函数、const成员、“&”取地址运算符重载)

                              

                              

    ---------------------------------------------------------------------------------------------

                           

    GetMonthday“辅助”函数 -- 获取当前月份日期函数

                     

    • 因为考虑到各月份日期可能不一样,二月还需要考虑闰年还是平年,
      所以可以单独写一个函数处理月份的情况,方便后续成员函数的实现

                         

    • assert断言:防止year(年份)或month(月份)传错

                         

    • 一年有12个月,定义一个有13个元素的数组,
      不使用第一个元素,之后的12个元素分别为1~12月各个月的对应日期(平年)

                       

    • 再单独判断2月的情况,如果year是闰年,再修改2月的日期为29天

                      

    • 最后通过数组下标返回对应月的日期
      图示:

      【C++初阶】五、类和对象(日期类的完善、流运算符重载函数、const成员、“&”取地址运算符重载)

                                

                                

      ---------------------------------------------------------------------------------------------

                             

      operator==函数  --  “==”运算符重载函数

                       

      • 通过隐藏的this指针来依次判断两日期的年、月、日是否相同并返回结果
        图示:

        【C++初阶】五、类和对象(日期类的完善、流运算符重载函数、const成员、“&”取地址运算符重载)

                                

                                  

        ---------------------------------------------------------------------------------------------

                               

        operator!=函数  --  “!=”运算符重载函数

                         

        • 复用“==”运算符重载函数,对其结果取反,就能实现“!=”运算符重载函数了
          图示:

          【C++初阶】五、类和对象(日期类的完善、流运算符重载函数、const成员、“&”取地址运算符重载)

                                  

                                    

          ---------------------------------------------------------------------------------------------

                                 

          operator>函数  --  “>”运算符重载函数

                           

          • 先比较年份,“年大就大”;
            如果年份相等,“月大就大”;
            如果年份相等,月份也相等,“天大就大”;
            大就返回true

                       

          • 除此以外,就是两日期小于等于的情况了,返回false
            图示:

            【C++初阶】五、类和对象(日期类的完善、流运算符重载函数、const成员、“&”取地址运算符重载)

                                    

                                      

            ---------------------------------------------------------------------------------------------

                                   

            operator>=函数  --  “>=”运算符重载函数

                             

            • 复用“>”和“==”运算符重载函数即可实现">="运算符重载函数
              图示:

              【C++初阶】五、类和对象(日期类的完善、流运算符重载函数、const成员、“&”取地址运算符重载)

                                      

                                        

              ---------------------------------------------------------------------------------------------

                                     

              operator(const Date& y); //大于 //“>=”运算符重载函数: bool operator>=(const Date& y); //大于等于 //“ y._day) { return true; } //上面已经写出了所有大于的情况,执行到这说明是小于等于: return false; //返回false } //“>=”运算符重载函数: bool Date::operator>=(const Date& y) //大于等于 { //直接复用“>”和“==”运算符重载函数即可: return *this > y || *this == y; /* * *this即左值对象,y即右值对象 * 通过复用“>”和“==”运算符重载函数判断并返回结果即可, * “>=” --> “>” 或 “==” */ } //“= y); /* * *this即左值对象,y即右值对象 * 通过复用“>=”运算符重载函数即可, * 如果不是“>=”,那就是“”运算符重载函数即可, * 如果不是“>”,那就是“”(或“ GetMonthDay(_year, _month)) /* * 先通过GetMonthDay函数获得当月的天数, * 再比较相加后的天数是否超过了当月的天数, * 只要超过了则进行进位,进位到月: * (while循环到没超过为止) */ { //天数减去一轮当前月天数: _day -= GetMonthDay(_year, _month); //减去的一轮当前月天数进位到月中: ++_month; //如果当前月进位后超过了12个月: if (_month == 13) { //将一轮月份进位到年: ++_year; //将月份重置为1月: _month = 1; } } return *this; } //“+”运算符重载函数: Date Date::operator+(int day) { Date tmp(*this); /* * 为了实现加法,加了后不改变d1对象(+=才会改变) * 先通过*this(即d1)拷贝出一个tmp, * 对tmp进行加法操作就不会改变d1对象了 */ /* * 复用 “+=运算符重载” ,只要 += 到d1的拷贝tmp上即可, * 就不会改变到d1对象,通过tmp返回d1的加法结果: */ tmp += day; //通过tmp返回d1的加法结果: return tmp; /* * 这里tmp是d1的拷贝,出了函数就销毁了, * 所以需要传值返回拷贝一份回主函数 */ } “+”运算符重载函数: d1 + 100(整数) ,计算d1日期的100天后的日期: //Date Date::operator+(int day) // “+” 不会改变d1对象 // //为了防止拷贝返回,使用引用返回 //{ // Date tmp(*this); // /* // * 为了实现加法,加了后不改变d1对象(+=才会改变) // * 先通过*this(即d1)拷贝出一个tmp, // * 对tmp进行加法操作就不会改变d1对象了 // */ // // //思路:当月天数满了进位到月,月满了则进位到年: // // tmp._day += day; //先将要加的天数加到当前的天数上 // // //开始进位(如果需要的话): // while (tmp._day > GetMonthDay(tmp._year, tmp._month)) // /* // * 先通过GetMonthDay函数获得当月的天数, // * 再比较相加后的天数是否超过了当月的天数, // * 只要超过了则进行进位,进位到月: // * (while循环到没超过为止) // */ // { // //天数减去一轮当前月天数: // tmp._day -= GetMonthDay(tmp._year, tmp._month); // // //减去的一轮当前月天数进位到月中: // ++tmp._month; // // //如果当前月进位后超过了12个月: // if (tmp._month == 13) // { // //将一轮月份进位到年: // ++tmp._year; // // //将月份重置为1月: // tmp._month = 1; // } // } // //return tmp; ///* //* 这里tmp是d1的拷贝,出了函数就销毁了, //* 所以需要传值返回拷贝一份回主函数 //*/ //} “+=”运算符重载函数: //Date& Date::operator+=(int day) //{ // //复用“+”运算符重载函数: // *this = *this + day; // /* // * 这里的*this(左值对象)和day(右值对象), // * 都是已经存在的对象,把已经存在的对象赋值给 // * 另一个已经存在的对象上,需要使用到赋值运算符重载函数 // * // * 使用“+”运算符重载函数将day日期加到*this日期上, // * 再使用赋值运算符重载函数把加上的日期赋值给*this, // * 完成“+”运算符重载函数的复用 // */ // // //返回“+=”结果: // return *this; //} /* * 一: * 如果先实现了“+”运算符重载函数, * 可以复用“+”运算符重载函数实现“+=”运算符重载函数 * * 二: * 如果先实现了“+=”运算符重载函数, * 那就可以复用“+=”运算符重载函数实现“+”运算符重载函数 * * 第一种方法的“+”需要进行两次对象拷贝, * “+=”通过复用“+”实现,需要三次对象拷贝, * 所以该方法总共需要五次拷贝 * * 第二种方法的“+=”不需要进行对象拷贝, * “+”中需要两次对象拷贝,该方法总共需要两次拷贝 * * 所以还是通过第二种方法实现“+=”和“+”比较好, * 而且实现加法最好使用“+=”,而不是“+”, * 因为“+=”不需要进行拷贝,“+”需要拷贝两次对象 */ //“-=”运算符重载函数: Date& Date::operator-=(int day) { /* * 可能有坏蛋右值传了个负数过来, * 如:d1 -= -100; * 这时就要进行特殊处理了: */ if (day min * 那么 n*flag = 相差天数(正)*1 ,返回正日期 * 如果我们假设错了:max

                                   

                                   


                                  

              Test.cpp -- 测试文件:

              //包含日期类头文件:
              #include "Date.h"
              //优化全缺省构造函数:
              void TestDate1()
              {
              	Date d1;
              	//打印d1日期:
              	d1.Print();
              	//全缺省构造函数的完善:
              	//初始化的日期可能不合法(月份):
              	Date d2(2023, 13, 1);
              	d2.Print();
              	//初始化的日期可能不合法(日期):
              	Date d3(2010, 2, 29); //2月可能没有29天
              	d3.Print();
              }
              //测试 “-” 和 “+”(日期-+整型):
              void TestDate2()
              {
              	//创建一个日期类对象:d1
              	Date d1(2023, 10, 24);
              	d1.Print();
              	//测试“-”运算符重载函数:
              	Date ret1 = d1 - 100; //隔几个月
              	ret1.Print(); //打印结果
              	Date ret2 = d1 - 10000; //跨越闰年
              	ret2.Print(); //打印结果
              	//测试“+”运算符重载函数:
              	Date ret3 = d1 + 100; //隔几个月
              	ret3.Print(); //打印结果
              	Date ret4 = d1 + 10000; //跨越闰年
              	ret4.Print(); //打印结果
              }
              //测试“前置++”和“后置++”:
              void TestDate3()
              {
              	//创建一个日期类对象:d1
              	Date d1(2023, 10, 24);
              	d1.Print();
              	++d1; 
              	//d1.operator++() -- “前置++”
              	d1.Print(); //2023/10/25
              	Date d2 = d1++;
              	//d1.operator++(int) -- “后置++”
              	d2.Print(); //先取到d1:2023/10/25,再++
              	d1.Print(); //2023/10/26
              }
              //测试“日期-日期”运算符重载函数:
              void TestDate4()
              {
              	//创建一个日期类对象:d1
              	Date d1(2023, 10, 24);
              	d1.Print();
              	//创建一个日期类对象:d2
              	Date d2(2024, 2, 10);
              	d2.Print();
              	//打印两日期相差的日期:
              	cout 
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]