【C++打怪之路Lv4】-- 类和对象(中)

news2024/11/6 7:24:21

🌈 个人主页:白子寰
🔥 分类专栏:C++打怪之路,python从入门到精通,数据结构,C语言,C语言题集👈 希望得到您的订阅和支持~
💡 坚持创作博文(平均质量分82+),分享更多关于深度学习、C/C++,python领域的优质内容!(希望得到您的关注~)

目录

类的6个默认成员函数

构造函数

概念 

六个特性

默认构造函数的意义

 析构函数

概念

四个特性

小结

 拷贝构造函数

概念

三个特性

总结

 赋值运算符重载

运算符重载

相等操作符重载函数(比较Date中的两个对象是否相等) 

在全局中

在类中

注意点

this 和 *this 的区别

​编辑

赋值运算符重载

赋值运算符重载格式

 注意点

赋值运算符重载 和 拷贝构造函数 的区别

 传值返回 和 传引用返回 的区别

前置++ 和 后置++ 重载

const成员

含义

在哪用

取地址及const取地址操作符重载

日期类的实现

Date.h

Date.cpp

Test.cpp


类的6个默认成员函数

1、特殊成员函数

2、不写编译器会自动生成



构造函数

概念 

构造函数是初始化对象不是开空间

C语言中没有初始化,会出现随机值


六个特性

  1. 函数名与类名相同
  2. 无返回值

  3. 对象实例化 自动调用 该函数

  4. 构造函数可以重载

  5. 如没有显式定义的构造函数,编译器自动生成(隐式的无参构造函数);反之,则不会自动生成

  • 注:①不显式写默认构造,对于内置类型成员变量,看编译器是否处理; 对于自定义类型成员变量才会调用它的 无参构造(不传参就可以调用的那个构造)

②默认构造函数包括:无参构造函数、全缺省构造函数、编译器默认生成的构造函数(隐式的无参构造函数)

6、内置类型成员变量在类中声明时可以给默认值

 


默认构造函数的意义

在两个栈实现一个队列,编译器给了初始化(在某种情况下有意义)




 析构函数

概念

对象销毁时自动调用析构函数,完成对象中的资源清理

C语言没有写Destroy,会造成内存泄漏


四个特性

  1. 析构函数名在类名前加~
  2. 无参数无返回值
  3. 一个类只能析构一个函数,析构函数不能重载
  4. 在生命周期结束时自动调用
  • 析构函数内置类型不做处理自定义类型调用它的析构
  • 析构函数可以显式写

 


小结

  1. 有资源清理(开空间)才需要析构函数;如Stack、Queue
  2. 有两种场景不需要显式析构,用默认生成的就OK了
  • ①没有资源清理,如Date
  • ②内置类型成员没有资源需要清理,剩下的都是自定义类型成员;如MyQueue



 拷贝构造函数

概念

用同类型的对象拷贝初始化


三个特性

  1. 拷贝构造函数是构造函数的一个重载形式
  2. 拷贝构造函数的参数只有一个且必须是类类对象的引用,使用传值方式编译器直接报错,会引发无穷递归
  3. 未显式定义,编译器会默认生成拷贝构造函数


总结

  1. 一般情况下,不需要显式写析构函数,就不用写拷贝构造函数(值拷贝)
  2. 如果 内部有指针 或者 一些值指向资源,需要显式写析构函数释放,需要写构造完成深拷贝; 如Satck、Queue、List




 赋值运算符重载

运算符重载


相等操作符重载函数(比较Date中的两个对象是否相等) 

在全局中

全局中写 operator== 函数,要屏蔽 Date类 中private

那封装性如何保证?友元 重载成员函数 解决

这里讲的是重载成员函数,把 内置类型成员 公有,这样在全局中函数就能 访问 内置类型成员

在类中

注意点

在主函数中


this 和 *this 的区别

赋值运算符重载

赋值运算符重载格式


 注意点


赋值运算符重载 和 拷贝构造函数 的区别


 传值返回 和 传引用返回 的区别

传值返回 会生成当前对象的一个拷贝,拷贝一个临时对象
引用返回 生成某别名,出了作用域就销毁了
总结 虽然引用返回减少了拷贝,但出了函数作用域,返回对象还在才能用引用(在静态)


前置++ 和 后置++ 重载




const成员

含义

const修饰的是*this,本质上是改变this的类型

在哪用

  1. 运算符重载
  2. 不改变自身

取地址及const取地址操作符重载

不显式实现,编译器默认生成




日期类的实现

Date.h

#pragma once

#include<iostream>
#include<stdlib.h>
using namespace std;

class Date
{
	// 友元函数,可以访问私有
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);

public:
	// 构造函数
	Date(int year, int month, int day);

	// 打印
	void Print();

	// 运算符重载
	// 实现</>,==就可以了,其他的复用(要建立栈帧,内联,不能声明和定义分离,在类里面定义就是内联)
	bool operator==(const Date& d) const;
	bool operator!=(const Date& d) const;
	bool operator>(const Date& d) const;
	bool operator>=(const Date& d) const;
	bool operator<(const Date& d) const;
	bool operator<=(const Date& d) const;

	static int GetMonthDay(int year, int month)
	{
		int GetMonthDayArr[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
		if (month == 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
		{
			return 29;
		}
		else return GetMonthDayArr[month];
	}

	// 检查日期是否正确
	bool checkDate()
	{
		if (_month < 1 || _month > 12 || _day <= 0 || _day > GetMonthDay(_year, _month)) return false;
		else return true;
	}

	// 日期 + 天数
	Date& operator+=(int day);
	Date operator+(int day) const;

	// 日期 - 天数
	Date& operator-=(int day);
	Date operator-(int day) const;

	// 前置++
	Date& operator++();
	// 后置++
	Date operator++(int) const;

	// 前置--
	Date& operator--();
	// 后置--
	Date operator--(int) const;

	// d1 - d2
	int operator-(const Date& d) const;

private:
	int _year;
	int _month;
	int _day;
};

// 流插入重载
ostream& operator<<(ostream& out, const Date& d);
// 流提取重载
istream& operator>>(istream& in, Date& d);

Date.cpp

#define _CRT_SECURE_NO_WARNINGS 1

#define _CRT_SECURE_NO_WARNINGS 1

#include"Date.h"

Date::Date(int year, int month, int day)
{
	//cout << "Date(int year, int month, int day)" << endl;

	_year = year;
	_month = month;
	_day = day;
}

void Date::Print()
{
	cout << _year << "-" << _month << "-" << _day << endl;
}

bool Date::operator==(const Date& d) const
{
	return 	this->_year == d._year
		&& this->_month == d._month
		&& this->_day == d._day;
}

bool Date::operator!=(const Date& d) const
{
	return !(*this == d);
}

bool Date::operator>(const Date& d) const
{
	if (this->_year > d._year) return true;
	else if (this->_year == d._year && this->_month > d._month) return true;
	else if (this->_year == d._year && this->_month == d._month && this->_day > d._day) return true;
	return false;
}

bool Date::operator>=(const Date& d) const
{
	return *this > d || *this == d;
}

bool Date::operator<(const Date& d) const
{
	return !(*this >= d);
}

bool Date::operator<=(const Date& d) const
{
	return !(*this > d);
}

// 日期 + 天数
Date& Date::operator+=(int day)
{
	if (day < 0) return *this -= -day;

	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		++_month;
		if (_month == 13)
		{
			++_year;
			_month = 1;
		}
	}
	return *this;
}

Date Date::operator+(int day) const
{
	Date tmp = *this;
	tmp += day;

	return tmp;
}

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

	_day -= day;
	while (_day <= 0)
	{
		--_month;
		if (_month == 0)
		{
			_month = 12;
			--_year;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}

Date Date::operator-(int day) const
{
	Date tmp = *this;
	tmp -= day;
	return tmp;
}

// 前置++
Date& Date::operator++()
{
	*this += 1;
	return *this;
}

// 后置++
Date Date::operator++(int) const
{
	Date tmp = *this;
	tmp += 1;
	return tmp;
}

// 前置--
Date& Date::operator--()
{
	*this -= 1;
	return *this;
}

// 后置--
Date Date::operator--(int) const
{
	Date tmp = *this;
	tmp -= 1;
	return tmp;
}

int Date::operator-(const Date& d) const
{
	Date max = *this;
	Date min = d;
	int n = 0, flag = 1;
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}

	while (min != max)
	{
		++min;
		++n;
	}

	return flag * n;
}

//ostream& Date::operator<<(ostream& out)
//{
//	out << _year << "-" << _month << "-" << _day << endl;
//	return out;
//}

ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "-" << d._month << "-" << d._day << endl;
	return out;
}

istream& operator>>(istream& in, Date& d)
{
	cout << "请输入年、月、日:";
	in >> d._year >> d._month >> d._day;
	if (!d.checkDate()) {
		cout << "输入的日期无效,请重新输入。" << endl;
		in.clear(); // 清除错误标志
		in.ignore(numeric_limits<streamsize>::max(), '\n'); // 忽略错误输入直到下一个换行符
		return in;
	}
	return in;
}

Test.cpp

#define _CRT_SECURE_NO_WARNINGS 1

#include"Date.h"
void test1()
{
	Date d1(2024, 9, 26);
	Date d2(2024, 9, 26);
	bool ret1 = d1 > d2;
	bool ret2 = d1 >= d2;
	bool ret3 = d1 < d2;
	bool ret4 = d1 <= d2;
	bool ret5 = d1 == d2;
	bool ret6 = d1 != d2;

	cout << ret1 << endl;
	cout << ret2 << endl;
	cout << ret3 << endl;
	cout << ret4 << endl;
	cout << ret5 << endl;
	cout << ret6 << endl;
}

void test2()
{
	Date d1(2024, 9, 26);
	Date d2(2024, 9, 26);

	// +=	// 11-15
	Date tmp = d1 -= -100;
	d1.Print();
	//tmp.Print();
	 + 
	//Date tmp2 = d2 + 50;
	//d2.Print();		// 9-26
	//tmp2.Print();	// 11-15

	//Date d3(2024, 9, 26);
	//Date d4(2024, 9, 26);

	 -=	//8-7
	//Date tmp3 = d3 -= 50;
	//d3.Print();
	//tmp3.Print();
	 - 
	//Date tmp4 = d4 - 50;
	//d4.Print();
	//tmp4.Print();
}

void test3()
{
	Date d1(2024, 9, 26);
	Date d2(2024, 9, 26);

	Date tmp = --d1;
	d1.Print();
	tmp.Print();

	Date tmp2 = d2--;
	d2.Print();
	tmp2.Print();
}

void test4()
{
	Date d1(2024, 9, 26);
	Date d2(2024, 10, 1);
	int ret = d1 - d2;
	cout << ret << endl;
}

void test5()
{
	// 流插入和流提取 / 内置类型 直接用,为什么?
	//cout << "1";
	//printf("2");
	//cout << "3";
	//printf("4");

	Date d1(2024, 9, 26);
	//d1 << cout;	// 类中
	cout << d1;		// 全局
}

void test6()
{
	Date d1(2024,9,27);
	Date d2(2024,10,1);
	cin >> d1 >> d2;
	cout << d1 << d2;
}

void test7()
{
	const Date d1(2024, 9, 27);
	Date d2(2024, 9, 27);

	bool d3 = d1 > d2;
	Date d4 = d1 - 10;
}

int main()
{
	//test1();
	//test2();
	//test3();
	//test4();
	//test5();
	//test6();
	test7();
}



 

 ***********************************************************分割线*****************************************************************************
完结!!!
感谢浏览和阅读。

等等等等一下,分享最近喜欢的一句话:

“我从来没有后悔对任何人好,哪怕看错人,哪怕被辜负,哪怕撞南墙,因为我对你好不代表你有多好,只是因为,我很好!”。

我是白子寰,如果你喜欢我的作品,不妨你留个点赞+关注让我知道你曾来过。
你的点赞和关注是我持续写作的动力!!! 
好了划走吧。

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

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

相关文章

C语言第三周课

目录 一、C语言中基本语句的分类&#xff1a; 二、数据的输入和输出 1.putchar函数 2.getchar函数 3.printf函数 printf() 的正常输出格式&#xff1a; 输出控制符大全 4.scanf函数 三、顺序结构 四、选择结构 1.if 2.switch 五、循环结构 1.for循环 2.while循环 3.…

【读书笔记-《网络是怎样连接的》- 1】Chapter1-从Web浏览器开始

网络之旅的第一章&#xff0c;我们从在浏览器中输入url开始。本章主要介绍三部分内容。首先是在Web浏览器中输入URL后&#xff0c;浏览器是如何解析URL并生成HTTP请求消息的。生成请求消息后&#xff0c;浏览器需要将请求发送给Web服务器&#xff0c;需要知道Web服务器的IP地址…

2024年必考这个人工智能AI大模型证书!

2024必考这个人工智能AI大模型证书&#xff1a;名额有限&#xff0c;报满截止&#xff01; Chat GPT 的发布&#xff0c;让大语言模型成了人工智能的焦点。尤其近期发布的大模型各业务场景应用应接不暇&#xff0c;为行业带来新的发展机遇&#xff0c;甚至将重构AI行业。AI行业…

C语言系列4——指针与数组(1)

我们开始C语言的指针与数组 这部分开始进阶了&#xff0c;得反复学习 在开始正题之前&#xff0c;写说一下我们都知道当写一个函数的时候需要进行传参&#xff0c;当实参传递给形参的时候&#xff0c;形参是有独立空间的&#xff0c;那么数组传参又是怎么样的呢&#xff0c;我…

Docker的入门详解

What is docker&#xff1f; Docker是一个开源的应用容器引擎&#xff0c;它基于Go语言开发&#xff0c;并遵从Apache2.0协议。Docker允许开发者将他们的应用以及依赖包打包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的Linux或Windows操作系统的机器上&am…

MySQL高阶2004-职员招聘人数

目录 题目 准备数据 分析数据 实现 题目 一家公司想雇佣新员工。公司的工资预算是 70000 美元。公司的招聘标准是&#xff1a; 雇佣最多的高级员工。在雇佣最多的高级员工后&#xff0c;使用剩余预算雇佣最多的初级员工。 编写一个SQL查询&#xff0c;查找根据上述标准雇…

【Spring基础3】- Spring的入门程序

目录 3-1 Spring的下载3-2 Spring的 jar 包3-3 第一个 Spring程序第一步&#xff1a;添加spring context的依赖&#xff0c;pom.xml配置如下第二步&#xff1a;添加junit依赖第三步&#xff1a;定义bean&#xff1a;User第四步&#xff1a;编写spring的配置文件&#xff1a;bea…

Qt开发第一讲

一、Qt项目里面有什么&#xff1f; 对各个文件的解释&#xff1a; Empty.pro文件 QT core gui # 要引入的Qt模块&#xff0c;后面学习到一些内容的时候可能会修改这里 #这个文件相当于Linux里面的makefile文件。makefile其实是一个非常古老的技术了。 #qmake搭配.pr…

【C++篇】启航——初识C++(下篇)

接上篇【C篇】启航——初识C&#xff08;上篇&#xff09; 目录 一、引用 1.引用的概念 2.引用的基本语法 3.引用的特点 3.1 别名 3.2 不占用额外内存 3.3 必须初始化 3.4 不能为 NULL 4.引用的使用 4.1 函数参数传递 4.2 返回值 4.3 常量引用 5.引用和指针的关…

从数字化到智能化,智慧园区让管理更高效

在当今科技飞速发展的时代&#xff0c;园区管理也正经历着从数字化到智能化的深刻变革。智慧园区的建设&#xff0c;让管理变得更加高效、便捷和智能。 数字化是智慧园区建设的基础。通过物联网、大数据、云计算等技术&#xff0c;园区内的各种设施、设备和系统实现了互联互通…

基于Java的建筑节能监测系统+能源管理+公共建筑能耗监测系统+建筑能耗监测系统+节能监测系统+能源管理系统

介绍 建筑节能监测系统是基于计算机网络、物联网、大数据和数据可视化等多种技术融合形成的一套节能监测系统 系统实现了对建筑电、水、热&#xff0c;气等能源、资源消耗情况的实时监测和预警、动态分析和评估&#xff0c;为用户建立了科学、系统的节能分析方法&#xff0c;…

【Python|接口自动化测试】使用requests库发送HTTP请求

1.requests模块介绍 Python的requests模块是一个非常流行的第三方库&#xff0c;用于发送HTTP请求。它简化了与Web服务进行交互的过程&#xff0c;使得开发人员可以更方便地处理HTTP请求和响应。 本篇文章需要对HTTP和Python有一定的了解&#xff0c;只会解释关键性的操作 安…

【刷点笔试面试题试试水】找错—使用strlen()函数代替sizeof计算字符串长度

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: #include <iostream> using namespace std;void UpperCase(ch…

【2024工业3D异常检测文献】CMDIAD: 基于跨模态蒸馏驱动的多模态工业异常检测

Incomplete Multimodal Industrial Anomaly Detection via Cross-Modal Distillation 1、Background 近年来&#xff0c;基于3D点云和RGB图像的多模态工业异常检测(IAD)研究强调了利用模态间的冗余性和互补性对于精确分类和分割的重要性。 在项目中&#xff0c;提出了CMDIAD方…

20240930编译orangepi5的Android12使用HDMI0输出

20240930编译orangepi5的Android12使用HDMI0输出 2024/9/30 9:44 缘起&#xff0c;3月份的时候&#xff0c;看PDD拼多多的优惠券给力&#xff01; 就入手了香橙派Orange Pi 5。 自从制作TF卡的启动卡的时候&#xff0c;坏了一张SanDisk的32GB的TF卡。 从此就对TF卡启动无比抵触…

【微信小程序前端开发】入门Day01 —— 小程序页面组成、组件使用及协同开发发布指南

小程序的项目结构 pages 用来存放所有小程序的页面 utils 用来存放工具性质的模块&#xff08;例如&#xff1a;格式化时间的自定义模块&#xff09; app.js 小程序项目的入口文件 app.json 小程序项目的全局配置文件 app.wxss 小程序项目的全局样式文件 project.config.json 项…

理解线程库和线程排斥(锁)

理解线程库 线程要有独立属性 a.独立栈结构 b.寄存器中的上下文 在进程地址库内&#xff0c;维护栈的设备只有一套&#xff0c;如何保证线程都有独立栈&#xff1f; 每个新线程的栈由库维护&#xff0c;库会在堆上开辟一段空间。 默认地址空间的栈由主线程使用 如何理解pt…

SpringBoot框架下体育馆管理系统的构建

1引言 1.1课题背景 当今时代是飞速发展的信息时代。在各行各业中离不开信息处理&#xff0c;这正是计算机被广泛应用于信息管理系统的环境。计算机的最大好处在于利用它能够进行信息管理。使用计算机进行信息控制&#xff0c;不仅提高了工作效率&#xff0c;而且大大的提高了其…

被Karpathy誉为“蕴藏着类似ChatGPT的机会的AI产品Notebook LM”,它到底做对了什么?

就在昨天&#xff0c;Karpathy在X上连续发布了多条安利帖&#xff0c;强烈地给大家推荐一个AI产品NotebookLM。 嘶&#xff5e;给周围人疯狂种草并不稀奇&#xff0c;但Karpathy的推荐理由给NotebookLM戴了一个高帽子-他提到这款产品让人联想到ChatGPT。 这种就令人好奇&#…

线性模型到神经网络

&#x1f680; 在初始神经网络那一节&#xff08;链接如下&#xff1a;初始神经网络&#xff09;的最后&#xff0c;我们通过加大考虑的天数使得我们最后得到的模型Loss最终停留在了0.32k&#xff0c;当我们在想让模型更加准确的时候&#xff0c;是做不到的&#xff0c;因为我们…