C++类(3)

news2024/12/27 7:19:59

1.如果一个类什么成员都没有,简称空类

但是空类真的什么都没有吗?

并不是,任何类什么都不写,编译器会自动生成以下6个默认成员函数

1.构造函数 

class Date
{
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void print(void)
		{
			cout << _year << _month << _day << endl;
		}
private:
	int _year;
	int _month;
	int _day;
};

int main(void)
{
	Date d1;
	d1.Init(2005, 4, 14);
	d1.print();
	return 0;
}

对于Date类,可以通过Init共有的方法给对象设置信息,但是每次创建新的对象,都要取调用Init函数,好麻烦啊!那能不能在创建对象的时候就把信息设置进去呢?

这个时候就可以用构造函数了

class Date
{
public:
	 Date (int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	
	Date()
	{

	}
	void print(void)
		{
			cout << _year << _month << _day << endl;
		}
private:
	int _year;
	int _month;
	int _day;
};

int main(void)
{
	Date d1(2005, 4, 14);//调用带参数的构造函数
	Date d2;//调用无参构造函数
	Date d3();//编译器会报错
	//如果通过无参构造函数创建对象的时,对象后面不用跟括号,否则就成了函数声明,比如d3
	d1.print();
	return 0;
}

这个地方Date d1(2005,4,14)不会被当作函数声明是因为,函数声明里面是类型

但是Date d3()编译器就无法判断了!

构造函数是特殊的成员函数,但需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象!

其特征如下

1.函数名与类名相同(都是Date)

2.无返回值(不能写返回值,包括void也不可以)

3.对象实例化时编译器自动调用对应的构造函数

4.构造函数可以重载

那么如果我没有显示定义构造函数,则C++编译器会自动生成一个无参的默认的构造函数,一旦用户显示定义编译器将不再生成

这也就是为啥上面两个例子,不管我写不写构造函数

Date d1;
Date d2;

这种都可以编译通过

本质上编译器帮你写了一个

Date()
{

}

因此你会发现如果我这

因此你发现如果我这样写编译器就会报错

本质上是因为我自己写了显示定义函数,导致原本的无参的默认的构造函数消失了! 

但是你会发现一件很神奇的事就是,哪怕有这个默认的无参构造函数,但是我依然打印出来的是一个随机值,那么这个默认的无参构造函数的意义在哪呢?

 

1.一般情况下,有内置成员变量,就需要自己写构造函数,不能用编译器具体生成的

2.全部都是自定义类型成员,可以考虑让编译器自己生成

此外,这个地方是随机值的原因是没有初始化

(1).内置类型,基本类型,语言本身定义的基础类型,

   如int /char/double/指针等 

(2).自定义,struct /class等等定义的类型

我们对于内置类型等等(1)编译器不做处理,自定义类型(2)会去调他的默认构造

当然有些编译器也会对内置类型等等(1)处理,但那是个性化行为,并不是所有编译器都这么做!

注意!:C++11中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在类中声明可以给默认值

就像下面这样

class Date
{
public:
	void print(void)
		{
			cout << _year << _month << _day << endl;
		}
private:
	//内置类型  C++11支持 这里不是初始化只是声明 不开辟空间
	//这里给的是默认的缺省值,给编译器生成默认构造函数用
	int _year=2005;
	int _month=4;
	int _day=14;
};

int main(void)
{
	Date d1;
	d1.print();
	return 0;
}

但是如果自己写了显示定义函数,那个缺省值就没用了!

有了缺省值,我们传参传几个都可以!同样这种由于构造函数支持重载,也需要和重载函数一样避免歧义!

无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个

注意:无参构造函数和全缺省构造函数,我们没写编译器默认生成的构造函数,都可以认为是默认的构造函数

2.析构函数

构造函数可以帮助我们完成初始化,那么有没有什么函数可以帮助我们完成销毁呢?

答案就是析构函数

class stack
{
public:
	stack(size_t capacity = 3)//构造函数
	{
		_arry = (Datetype*)malloc(sizeof(Datetype) * capacity);
		if (_arry == NULL)
		{
			perror("malloc fail");
		}
		_capacity = capacity;
		_size = 0;
	}
	void push(Datetype data)
	{
		//Checkcapacity()这个地方还有一个检查容量的函数暂时省略不写
		_arry[_size] = data;
		_size++;
	}
	
	~stack()//析构函数
	{
		if (_arry)
		{
			free(_arry);
			_arry = 0;
			_capacity = 0;
			_size = 0;
		}
	}
private:
	Datetype* _arry;
	int _capacity;
	int _size;
};

int main(void)
{

	stack d1(66);
	d1.push(1);
	d1.push(11);
	return 0;
}

析构函数是特殊的成员函数,其特征如下:

1.析构函数名是在类名前面加一个~

2.无参数无返回值(无返回值也不能写void)

3.一个函数只能有一个析构函数,若未显示定义,系统会自动生成默认的析构函数。

注意:析构函数不能重载

4.对象生命周期结束时,C++编译系统会自动调用析构函数

比如上面那个例子就是在return 0;前调用析构函数!

我们来看下面这个例子

class Time
{
public:
	~Time()
	{
		cout << "~Time()" << endl;
	}
private:
	int _hour;
	int _minute;
	int _second;
};

class date
{

private:
	int _year=2005;
	int _month=4;
	int _day=14;
	Time arry;
};
int main(void)
{
	date a;
	return 0;
}

为啥我调用的是date打印的却是Time的析构函数呢?

首先date里面的三个变量_year,_month,_day都是内置类型成员,销毁时不需要资源清理,最后系统直接将其内存回收即可;

但是arry是Time类是自定义类型,date销毁的时候,会将date里面的四个变量都销毁,所以销毁arry要调用Time的析构函数,

但是main函数里面不能直接调用Time的析构函数,实际要释放的是Date类的对象,所以编译器会调用date类的析构函数,

但是date没有提供显示的析构函数,因此编译器会给date生成一个默认的析构函数,目的是在其内部调用time类的析构函数,

即当date类被销毁时,要保证其内部每个自定义对像都可以正确销毁

注意:销毁哪个那个类的对象则调用那个类的析构函数

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

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

相关文章

kubernetes简介及安装部署

目录 一、kubernetes简介 1、k8s的概念 2、k8s各个组件及用途 3、k8s各组件之间的调用关系 4、k8s常用名词概念 5、k8s的分层架构 二、kubernetes安装部署 1、k8s集群环境搭建 2、本地解析、swap禁用 3、安装docker 4、复制harbor仓库中的证书并启动docker 5、设定d…

基于Cesium.js的可视化大屏,效果绝对的震撼!

基于 Cesium.js 的可视化大屏确实能带来震撼的效果。Cesium.js 强大的三维渲染能力&#xff0c;能够逼真地呈现地理信息和各种数据模型。 在大屏上&#xff0c;广袤的地形地貌、精细的建筑模型以及动态的数据展示&#xff0c;仿佛将观众带入一个全新的虚拟世界。无论是用于地理…

网络分析仪——提升网络性能的关键工具

目录 什么是网络分析仪&#xff1f; 1. 实时流量监控 2. 历史数据回溯分析 3. 网络性能关键指标监测 4. 可视化界面与报告生成 总结 在当今的数字化世界&#xff0c;网络的稳定性和性能直接影响企业的运营效率。网络拥堵、延迟和丢包等问题会导致用户体验的下降&#xff…

“屏” 步青云:轻松开启录屏功能,Windows 实例教学

你知道 Windows 的录屏功能怎么打开吗&#xff1f;在当今数字化时代&#xff0c;录屏功能成为了许多人工作、学习和娱乐中的得力助手。无论是制作教学视频、记录游戏精彩瞬间&#xff0c;还是为线上会议留存资料&#xff0c;掌握录屏技能都至关重要。今天我们不仅会介绍 Window…

springboot智能网上问诊系统-计算机毕业设计源码99634

摘要 智能网上问诊系统作为医疗健康领域的重要应用之一&#xff0c;为患者提供了便捷的医疗服务途径。本研究旨在基于Springboot框架设计和实现一套智能网上问诊系统&#xff0c;结合医疗专业知识&#xff0c;实现患者与医生之间的在线咨询和诊疗服务。 通过对Springboot框架…

如何从模块内部运行 Pytest

在 Python 中&#xff0c;pytest 是一个强大的测试框架&#xff0c;用于编写和运行测试用例。通常我们会在命令行中运行 pytest&#xff0c;但是有时你可能希望从模块或脚本的内部运行 pytest&#xff0c;比如为了自动化测试或集成到某个工作流程中。 1、问题背景 当你从模块…

网络爬虫-数美滑块验证码

仅供研究学习使用。 今天带来的是数美滑块验证码的逆向 目标站 --> 传送门 解决此类验证码 首先要解决滑动距离的判定 无论是使用selenium还是使用协议的方式来破解 都绕不开滑动距离的识别 滑动距离可以参考以前我博客上的方式&#xff0c;或者找一找开源的一些算法&am…

秋招突击——8/6——万得数据面试总结

文章目录 引言正文面经整理一1、讲一下java的多态&#xff0c;重载&#xff0c;重写的概念&#xff0c;区别2、说一下Java的数组&#xff0c;链表的结构&#xff0c;优缺点3、创建java线程的方式有哪些&#xff0c;具体说说4、创建线程池呢、每个参数的意义5、通过那几种方式保…

java基础(5)继承与多态

目录 ​编辑 1.前言 2.正文 2.1继承 2.1.1继承概念 2.1.2继承语法 2.1.3子类访问父类 2.1.4super关键字 2.2多态 2.2.1多态概念 2.2.2多态条件 2.2.3重写 2.2.4向上转型与向下转型 2.2.5为什么要使用多态 3.小结 1.前言 哈喽大家好啊&#xff0c;今天继续来为大…

汽车开发流程管理工具赋能安全与质量

随着数字化、人工智能、自动化系统及物联网技术的迅速发展&#xff0c;工程驱动型企业正面临重大转型挑战&#xff0c;亟需加速并深化其变革步伐。众多企业正试图通过采用基于模型的系统工程(MBSE)、产品线工程(PLE)、ASPICE、安全、网络安全、软件定义汽车、敏捷和精益开发实践…

微信小程序上传组件封装uploadHelper2.0使用整理

一、uploadHelper2.0使用步骤说明 uploadHelper.js ---上传代码封装库 cos-wx-sdk-v5.min.js---腾讯云&#xff0c;对象存储封装库 第一步&#xff0c;下载组件代码&#xff0c;放置到自己的小程序项目中 第二步、 创建上传对象&#xff0c;执行选择图片/视频 var _this th…

【java Web如何开发?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

讯飞与腾讯云:Android 实时语音识别服务对比选择

在 移动端 接入实时语音识别方面&#xff0c;讯飞和腾讯云都是优秀的选择&#xff0c;但各有其特点和优势。以下是对两者的详细比较&#xff1a; 一、讯飞语音识别 1.1 讯飞实时语音识别介绍 1.1.1 功能特点 1.支持多种语言识别&#xff0c;满足不同语种用户的需求。(普通话/…

Kafka之消费者组与消费者

消费者&#xff08;Consumer&#xff09;在Kafka的体系结构中是用来负责订阅Kafka中的主题&#xff08;Topic&#xff09;&#xff0c;并从订阅的主题中拉取消息后进行处理。 与其他消息中间件不同&#xff0c;Kafka引入一个逻辑概念——消费组&#xff08;Consumer Group&…

使用excel.js(layui-excel)进行layui多级表头导出,根据单元格内容设置背景颜色,并将导出函数添加到toolbar

本段是菜狗子的碎碎念&#xff0c;解决办法请直接从第二段开始看。layui多级表头的导出&#xff0c;弄了两天才搞定&#xff0c;中途一度想放弃&#xff0c;还好坚持下来了。一开始用的是layui的toolbar里自带的那个导出&#xff0c;但是多级表头没有正常导出&#xff0c;单元格…

FPGA学习(6)-基础语法参数化设计阻塞与非阻塞

目录 1.两种参数化不改变源文件&#xff0c;只改仿真文件的值 2.参数化设计实现模块的重用 2.1不用参数化方法 2.1.1源文件 2.1.2仿真文件 2.1.3仿真波形及实验 2.2 用参数方法 2.2.1调用之前写的led灯闪烁模块&#xff0c;在本源函数中&#xff0c;例化4次调用之前的模…

【pyspark学习从入门到精通7】DataFrames_2

目录 创建 DataFrames 生成我们自己的 JSON 数据 创建 DataFrame 创建临时表 简单的 DataFrame 查询 DataFrame API 查询 SQL 查询 创建 DataFrames 通常&#xff0c;您会通过使用 SparkSession&#xff08;或在 PySpark shell 中调用 spark&#xff09;导入数据来创建 …

SpinalHDL之错误集(一)

本文作为SpinalHDL学习笔记第七十六篇&#xff0c;作为错误集使用&#xff0c;类似高中生的错题集&#xff0c;记录使用SpinalHDL过程中遇到的问题&#xff0c;小到语法错误、版本兼容问题&#xff0c;大到SpinalHDL库函数错误等等&#xff0c;持续更新。 SpinalHDL学习笔记总…

记录 ruoyi-vue-plus在linux 部署遇到的问题

整理 linux 文件不要放在 /, 根目录下&#xff0c;要放在 home 文件夹下。docker 启动mysql 容器&#xff0c;映射的 my.cnf 文件不能设置太高权限&#xff0c;权限太高有安全问题&#xff0c;无法读取。 linux 使用注意事项 docker 文件夹 部署在home文件夹下 总结学习到的…

Asp.Net Core 发布 IIS、docker、Azure、文件夹、AAS、ASF、AWM等

发布 微软资料 微软资料 在 IIS 工作进程 (w3wp.exe) 内托管 ASP.NET Core 应用&#xff0c;称为进程内托管模型。 将 Web 请求转发到运行 Kestrel 服务器的后端 ASP.NET Core 应用&#xff0c;称为进程外托管模型。 发布到IIS 》》》Asp.net 之前 》》》 Asp.net Core …