C++ 写一个Data类的注意问题

 Data类

声明和定义分离的一些问题

声明里面我们不带缺省参数,定义我们给缺省参数,如下面两段代码:

Data.h#pragma once
#include<iostream>
using namespace std;
class Data
{
public:Data(int year,int month,int day);private:int _year;int _month;int _day;};
Data.cpp#include"Data.h"Data::Data(int year=1 , int month=1 , int day=1 ){_year = year;_month = month;_day = day;}

现在我们在main函数调用:

d1没报错,d2报错了:

这是因为我们main函数那个文件包的是.h文件,声明我们没有给缺省参数,声明就好比一种承诺,

没给参数,我们d2没有默认参数就过不了。

我们给个默认参数看看:

#pragma once
#include<iostream>
using namespace std;
class Data
{
public:Data(int year = 1, int month = 1, int day = 1);
private:int _year;int _month;int _day;};

声明和定义不能同时给默认参数,我们把定义的默认参数去了就可以了。

OK,我们写个print函数就可以把日期打印出来看看了:

Data.cppvoid Data:: print(){cout << _year << "年" << _month << "月" << _day << "日" << endl;}

我们发现上面这段日期是有问题的,有点的是闰年,有的是13月,是一些不合法日期,所以我们要加日期有效判断。

日期判断

引用上一篇文章写的:

int Getmonth(int year,int month){int GetArry[13] = {0, 31,28,30,31,30,31,30,31,30,31,30,31 };if (month==2&&(month % 4 == 0 && month % 10 == 0 || month % 400 != 0)){return 29;}return GetArry[month];}

可以在Getmonth函数前面加一个static,因为Getmonth肯定会被频繁调用,每一次都进来会造成消耗,所以用static让它具有全局属性。

然后我们给输入的日期加判断:

拷贝构造

日期类需不需要我们自己写拷贝构造,不需要,因为日期类就三个成员变量:int _year ,int _month,int  _day,全是内置类型,编译器会自动生成拷贝构造:

    Data d1(2003,11,33);d1.print();Data d2(d1);d2.print();

运算符重载


bool Data::operator<=(Data d2)
{if (_year <= d2._year){return true;}if (_year <= d2._year && _month <= d2._month){return true;}if (_year <= d2._year && _month <= d2._month && _day <= d2._day){return true;}else{return false;}
}bool Data::operator==(Data d2)
{return _year == d2._year&& _month == d2._month&& _day == d2._day;
}bool Data::operator>=(Data d2)
{return !(*this <= d2) || *this == d2;
}bool Data::operator<(Data d2)
{return !(*this <= d2);
}bool Data:: operator!=(Data d2)
{return !(*this == d2);
}

赋值运算符重载

Data& Data::operator=(const Data& d3)
{this->_year = d3._year;this->_month = d3._month;this->_day = d3._day;return *this;
}
Data d1(2003, 11, 33);Data d3(2003, 11, 22);Data d4(2000, 12, 3);d1 = d3 = d4;d1.print();d3.print();d4.print();

用operator+ 实现两个日期类相加

用+运算符重载实现两个日期类相加。

 直接用上篇文章的内容,如下代码实现两个日期类相加:

Data& Data:: operator+(int  day)
{Data temp(*this);//天数相加temp._day += day;//如果月满了while (temp._day > Getmonth(_year, _month)){//天数减去满月的天数temp._day -= Getmonth(_year, _month);//从当前月进入下一个月++temp._month;}//如果12个月都满了if (temp._month == 13){//当前年进入下一年++temp._year;//把月置为下一年的一月temp._month = 1;}return temp;
}
	mainData d1(2003, 11, 29);Data d2 = d1 + 200;d1.print();d2.print();

 原因:

通过调试发现,都已经超过12月了,还没有进入month==13的判断里面,这是因为whil循环没结束,要么改while循环条件,要么把month==13的if判断放到while里面修改后的代码:

static int  Getmonth(int year, int month)
{int GetArry[13] = { 0, 31,28,30,31,30,31,30,31,30,31,30,31 };if (month == 2 && (year% 4 == 0 && year % 100 == 0 || year % 400 != 0)){return 29;}return GetArry[month];
}Data& Data::operator+=(int day)
{*this += day;return *this;
}Data& Data:: operator+(int  day)
{Data temp(*this);//天数相加temp._day += day;//如果月满了while (temp._day > Getmonth(_year, _month)){//天数减去满月的天数temp._day -= Getmonth(_year, _month);//从当前月进入下一个月++temp._month;//如果12个月都满了if (temp._month == 13){//当前年进入下一年++temp._year;//把月置为下一年的一月temp._month = 1;}}return temp;
}
mainData d1(2003, 11, 29);d1 += 200;d1.print();

复用 ”+"实现 “+=”

 

注意不能这样写:

因为我们要服用 "operator+"实现"+=”功能,所以不能使用  “+=",因为"+="功能还没实现。

运行:

Data d1(2003, 11, 29);d1 += 200;d1.print();

 

operator-=

Date& Date:: operator-=(int  day)
{_day -= day;while (_day <=0){--_month;if (_month == 0){_year;_month = 12;}_day += Getmonth(_year, _month);}return *this;
}

 

如果我们这样写呢?

Date d1(2003, 11, 29);d1 -= -2000;d1.print();

 会偏移预期效果:

 因为我们没有考虑day为负数的情况。

d1-=2000   ==> d1=d1=-(-2000)  ==>d1=d1+2000  ==>d1+=2000;

我们复用一下operator+=就可以了。

Date& Date:: operator-=(int  day)
{if (day < 0){return *this += (-day);}

 同样的

Date d1(2003, 11, 29);d1 += -2000;d1.print();

也可以复用operator-=

没改之前:

 改了之后:

Date& Date::operator+=(int day)
{if (day < 0){return *this -= day;}*this =*this+day;return *this;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/125540.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【错误解决方案】ModuleNotFoundError: No module named ‘xgboost‘

1. 错误提示 在尝试导入名为xgboost的模块时出现了ModuleNotFoundError。 错误提示&#xff1a;ModuleNotFoundError: No module named xgboost 这个错误通常意味着Python环境中没有安装你试图导入的模块。 2. 解决方案 安装xgboost模块即可解决上述问题。 可以通过Python…

Web3公链之Cosmos生态的项目Celestia

文章目录 Web3公链之Cosmos生态的项目&#xff1a;模块化区块链Celestia什么是CelestiaCelestia网络架构数据可用性问题有哪些可用的解决方案&#xff1f; 发展历史运行节点参考 Web3公链之Cosmos生态的项目&#xff1a;模块化区块链Celestia 什么是Celestia 官网&#xff1a…

项目部署之OpenResty

项目部署之OpenResty 1. OpenResty介绍 OpenResty 是一个基于Nginx的高性能Web平台&#xff0c;用于方便地搭建能够处理超高并发、扩展性极高的动态Web应用、Web服务和动态网关。具备下列特点&#xff1a; 具备Nginx的完整功能基于Lua语言进行扩展&#xff0c;集成了大量精良…

hdlbits系列verilog解答(加减法器)-28

文章目录 一、问题描述二、verilog源码三、仿真结果一、问题描述 可以通过将其中一个输入变为负来从加法器构建加法器-减法器,这相当于将其输入反相然后加 1。最终结果是一个可以执行两个操作的电路:(a + b + 0) 和 (a + ~b + 1)。如果您想更详细地解释该电路的工作原理…

怎么理解电流超前电压、电压超前电流?

电容和电感&#xff0c;电压超前电流&#xff0c;电流超前电压都是我们经常听到的。作为非专业人士&#xff0c;这些听起来确实有点摸不着头脑&#xff0c;今天特别查了下电容、电感、电压电流相关资料&#xff0c;总算是弄明白了&#xff0c;在此特地记录下&#xff01; 1. 电…

【LeetCode:150. 逆波兰表达式求值 | 栈】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

一篇文章入门KNN算法

文章目录 KNNKNN算法KNN in practice推荐系统我们想回答什么问题&#xff1f;探索、清理和准备数据使用算法 Summary 参考文献 KNN 监督学习是一种依赖输入数据来学习函数的算法&#xff0c;该函数在给定新的未标记数据时可以产生适当的输出。 监督学习用于解决分类或回归问题…

LLM - 训练与推理过程中的 GPU 算力评估

目录 一.引言 二.FLOPs 和 TFLOPs ◆ FLOPs [Floating point Opearation Per Second] ◆ TFLOPs [Tera Floating point Opearation Per Second] 三.训练阶段的 GPU 消耗 ◆ 影响训练的因素 ◆ GPT-3 训练统计 ◆ 自定义训练 GPU 评估 四.推理阶段的 GPU 消耗 ◆ 影响…

Pap.er for Mac:高清壁纸应用打造你的专属视觉盛宴

在浩瀚的互联网海洋中&#xff0c;你是否曾为寻找一张心仪的高清壁纸而烦恼&#xff1f;或者是在大量的壁纸应用中感到困扰&#xff0c;不知道哪一个能满足你的需求&#xff1f;今天&#xff0c;我要向你介绍的&#xff0c;是一款独特的5K高清壁纸应用——Pap.er for Mac。 Pa…

leetcode:374. 猜数字大小(二分查找)

一、题目 函数原型&#xff1a;int guessNumber(int n) 二、思路 本题其实就是从 1 - n 中找出所要的答案。利用guess函数来判断数字是否符合答案。 答案小于当前数字&#xff0c;guess函数返回-1 答案等于当前数字&#xff0c;guess函数返回0 答案大于当前数字&#xff0c;gue…

Android NDK开发详解之ndk-build 脚本

Android NDK开发详解之ndk-build 脚本 内部原理从命令行调用选项可调试 build 与发布 build要求 ndk-build 脚本使用 NDK 的基于 Make 的构建系统构建项目。我们针对 ndk-build 使用的 Android.mk 和 Application.mk 配置提供了更具体的文档。 内部原理 运行 ndk-build 脚本相…

JVM 分代垃圾回收过程

堆空间划分了代&#xff1a; 年轻代&#xff08;Young Generation&#xff09;分为 eden 和 Survivor 两个区&#xff0c;Survivor 又分为2个均等的区&#xff0c;S0 和 S1。 首先&#xff0c;新对象都分配到年轻代的 eden 空间&#xff0c;Survivor 刚开始是空的。 当 eden …

招生报名缴费小程序开发笔记(上)

前期调研 1.数字化趋势&#xff1a; 随着社会的数字化转型&#xff0c;越来越多的教育机构倾向于采用数字工具来简化和优化他们的招生和报名过程。招生报名缴费小程序是应对这一趋势的一种解决方案&#xff0c;可以提供高效、方便、快速的在线招生渠道。2.用户需求&#xff1a…

Jtti:Apache服务的反向代理及负载均衡怎么配置

配置Apache服务的反向代理和负载均衡可以帮助您分散负载并提高应用程序的可用性和性能。下面是一些通用的步骤&#xff0c;以配置Apache反向代理和负载均衡。 1. 安装和配置Apache&#xff1a; 确保您已经安装了Apache HTTP服务器。通常&#xff0c;Apache的配置文件位于/etc…

VSCode-C/C++环境配置

0.下载VSCode VSCode官网 Visual Studio Code - Code Editing. Redefined 1.安装VSCode 2.编译器下载与配置 2.1下载编译器安装包 编译器的安装包分为两种一种是在线的一种是离线的,其区别的特点如下 在线安装&#xff08;只是个下载器&#xff0c;打开后还要下载各种东西…

RocketMQ生产者消息发送出去了,消费者一直接收不到怎么办?(Rocket MQ订阅关系一致性)

问题: 使用RocketMQ消息队列&#xff0c;生产者将数据发送出去了&#xff0c;但是生产者一致没接收到&#xff08;或者是间隔好几分钟&#xff0c;突然接收到一条数据&#xff09;怎么办&#xff1f;并且通过rocket web控制台查看消息的状态为NOT_ONELINE或者NOT_CONSUME&#…

韦东山D1S板子——利用xfel工具初始化内置64MB内存,并直接下载程序到内存运行

1、前言 &#xff08;1&#xff09;最近使用韦东山老师的D1S板子学习RISC-V架构知识&#xff0c;我是结合《RISC-V体系结构编程与实践》这本书的进行学习&#xff0c;其中韦东山老师对书中的代码做了部分移植&#xff0c;到MMU模块就没有在移植书中代码&#xff1b; &#xff0…

java毕业设计基于springboot+vue高校本科学生综评系统

项目介绍 本系统是利用Spring Boot框架而设计的一款结合用户的实际情况而设计的平台&#xff0c;利用VUE技术来将可供学生和管理员来使用的所有界面来显示出来&#xff0c;利用Java语言技术来编程实现用户和管理员所执行的各类操作业务逻辑&#xff0c;以MySQL数据库来存取系统…

把Qt6.2.4内置的标签打印了一遍

2023年10月31日&#xff0c;周二晚上 #include <QGridLayout> #include <QPushButton> #include <QLabel> #include <QApplication> #include <QStyle>int main(int argc, char *argv[]) {QApplication a(argc, argv);QWidget widget;widget.set…

Python 数学函数和 math 模块指南

Python 提供了一组内置的数学函数&#xff0c;包括一个广泛的数学模块&#xff0c;可以让您对数字执行数学任务。 内置数学函数。min() 和 max() 函数可用于在可迭代对象中查找最低或最高值&#xff1a; 示例&#xff1a;查找可迭代对象中的最低或最高值&#xff1a; x min…