类的默认成员函数——构造与析构函数

news2024/12/29 1:27:06

如果一个类中什么成员都没有,简称为空类。但是空类中真的什么都没有吗?

当然不是,任何类在什么都不写的情况下,编译器会自动生成6个默认成员函数

1.构造函数 

1.1概念引入

对于以下这个Date类,可以通过Init公有方法给对象设置日期,但是如果每次创建对象都调用该方法未免有一些麻烦,能否在创建对象时,就将信息设置进去

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


int main()
{
	Date d1;
	d1.Init(2022, 7, 5);
	d1.Print();

	Date d2;
	d2.Init(2022, 7, 6);
	d2.Print();
	return 0;
}

 构造函数:一个特殊的成员函数,名字和类名一样,创建类类型对象时由编译器自动调用,以保证每个数据成员都有一个合适的初始值,并且在对象的整个生命周期里只能调用一次。构造函数虽然名字叫构造,但是它的主要任务不是开空间创建对象,而是初始化对象。(类似Init函数的功能)

1.2特性 

  1. 函数名和类名相同
  2. 无返回值且不用写void
  3. 对象实例化时编译器自动调用对应的构造函数(与Init函数的最大区别)
  4. 构造函数可以重载,可以写多个构造函数,有多种初始化方式
class Date
{
public:
	//无参构造函数
	Date()
	{}

	//带参构造函数
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	//全缺省构造函数
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = yaer;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};

void TestDate()
{
	Date d1;//调用无参构造函数。注意!!如果通过无参构造函数创建对象时,对象后面不用跟括号,否则成了函数声明。
	Date d2(2015, 1, 1);//调用带参构造
}

5.如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义,编译器就不再生成。

6. C++把类型分成内置类型和自定义类型,内置类型就是语言提供的数据类型,如:int/char,自定义类型就是我们使用class/struct/union等自己定义的类型。编译器自动生成的构造函数对于内置类型的成员变量是不做处理的,对于自定义类型的成员变量会调用他的无参构造。

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

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

class Date
{
private:
	//这里是声明不是定义,不是初始化,是给缺省值
	int _year = 1970;
	int _month = 1;
	int _day = 1;
	Time_t;
};

int main()
{
	Date d;
	return 0;
}

8.无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只有一个。注意:无参构造函数,全缺省的构造函数,编译器默认生成的构造函数

  • 这三个都是默认构造函数
  • 三个只能存在一个,1和2同时存在会有调用歧义,没有1和2才会有3
  • 不传参数就可以调用的函数就是默认构造函数

1.3总结

自定义类型的尽头是内置类型,所以一般情况下构造函数需要自己显式地去实现,只有极少数情况让编译器默认生成 

2.析构函数 

2.1概念引入

析构函数

  1. 与构造函数的功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的,对象在销毁时会自动调用析构函数,完成对象中的资源清理工作。
  2. 由定义可知,不是所有的类都需要析构函数,比如Date日期类就不需要,因为没有资源需要回收

2.2特性

  1. 析构函数名是在类名前加上字符~
  2. 无参数无返回值类型
  3. 一个类只能有一个析构函数,若未显式定义,系统会自动生成默认的析构函数
  4. 析构函数不能重载
  5. 对象生命周期结束时,C++编译系统会自动调用析构函数

举例:Stack类的析构函数

~Stack()
{
	if (_array)
	{
		free(_array);
		_array = NULL;
		_capacity = 0;
		_size = 0;
	}
}

6.编译器生成的默认析构函数,对内置类型不做处理,对自定义类型调用它的析构函数

案例分析:

  • 程序运行结束后·,输出~Time( )
  • 在main方法中创建了Date对象d,而d中包含4个成员变量,其中_year,_month,_day三个是内置类型成员,销毁时不需要资源清理,最后系统直接将其内存回收即可
  • 而_t是Time类对象,所以在d销毁时,要将其内部包含的Time类_t对象销毁,所以要调用Time类的析构函数
  • 但是在main函数中不能直接调用Time类的析构函数,实际要释放的是Date类对象,所以编译器会调用Date类的析构函数
  • 而Date没有显示提供,则编译器会给Date类一个默认的析构函数,目的是在其内部调用Time类的析构函数
class Time
{
public:
	~Time()
	{
		cout << "~Time()" << endl;
	}
private:
	int _hour;
	int _minute;
	int _second;
};

class Date 
{
private:
	int _year = 1970;
	int _month = 1;
	int _day = 1;

	Time _t;
};

int main()
{
	Date d;
	return 0;
}

2.3总结

创建哪个类的对象就调用该类的构造函数,销毁哪个类的对象就调用该类的析构函数

有资源需要显式清理,就要写析构,比如Stack和List

有两种场景不需要显式写析构,默认生成就可以

  • 没有资源要清理的类,如Date
  • 内置类型成员没有资源要清理,剩下的都是自定义类型成员,如两个Stack构成的MyQueue类

构造函数和析构函数比较的抽象!祖师爷在制定的时候留存了一些些bug,还在不断改进,希望大家看完文章有所收获ovo

点赞收藏关注是博主不断更新优质好文的动力哦~ 

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

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

相关文章

北邮《计算机网络》传输层笔记

内容一览 缩写复习单词复习传输层前言传输协议的要点拥塞控制UDPTCP VS UDPTCP 缩写复习 AIMD XCP ECN WFQ max-min-fair ARQ PAWS TSAP NSAP TCP UDP RTT SCTP SACK NAK RST MSS 单词复习 inverse multiplexing(SCTP) convergence crashed machine protocol scenarios asym…

IIC学习笔记

目录 #I2C涉及相关知识 #I2C相关介绍 欢迎指正&#xff0c;希望对你&#xff0c;有所帮助&#xff01;&#xff01;&#xff01; 个人学习笔记&#xff0c;参考文献&#xff0c;链接最后&#xff01;&#xff01;&#xff01; #I2C涉及相关知识 SDA串行数据线&#xff1a; Ser…

GB28181视频汇聚平台EasyCVR接入Ehome设备视频播放出现异常是什么原因?

多协议接入视频汇聚平台EasyCVR视频监控系统采用了开放式的架构&#xff0c;系统可兼容多协议接入&#xff0c;包括市场标准协议&#xff1a;国标GB/T 28181协议、GA/T 1400协议、JT808、RTMP、RTSP/Onvif协议&#xff1b;以及主流厂家私有协议及SDK&#xff0c;如&#xff1a;…

RK3568平台(音频篇)耳机插拔检测

一.硬件原理图 耳机输出硬件原理图&#xff1a; 耳机实物图&#xff1a; 耳机插入硬件原理&#xff1a; 耳机插入后HP_DET_L会连接耳机的GND&#xff0c;从而实现HP_DET_L叫从高到低的状态。 耳机插入软件原理&#xff1a; 软件需要在驱动里面定时的读取gpio的状态&#xf…

2024期权交易佣金手续费最低是多少?期权交易有哪些成本?

显性成本 期权交易的显性成本包含期权交易的佣金和交易所费用&#xff0c;分别支付给券商和交易所&#xff0c;统一由券商代收。 佣金 期权佣金是期权交易时支付给券商的费用&#xff0c;佣金通常以交易金额的一定比例计算&#xff0c;可以是固定费用&#xff0c;也可以是滑…

尽管与 ChatGPT 达成了合作,但据报道苹果仍在与 Meta 进行人工智能谈判

苹果最近宣布计划将人工智能纳入 iOS 18 以及新的 iPhone 16 和 iPhone 16 Pro 机型中&#xff0c;并开始与潜在的生成式人工智能合作伙伴 Meta 进行讨论。 据《华尔街日报》报道&#xff0c;苹果已与 Meta 就将其跨平台使用的生成式人工智能模型整合到 Apple Intelligence 中…

avi格式视频提示无法播放错误,怎么解决?

AVI视频属于一种无损质量的视频格式&#xff0c;一般来说是兼容Windows系统播放的。播不了可能是由以下原因导致的&#xff1a; 1.文件损坏&#xff1a;可能是原文件在转码压缩的过程中操作不当&#xff0c;导致数据丢失、文件损坏。 2.播放器格式不支持&#xff1a;可能系统的…

计算机图形学入门16:阴影映射

1.前言 前面几篇关于光栅化的文章中介绍了如何计算物体表面的光照&#xff0c;但是着色并不会进行阴影的计算&#xff0c;阴影需要单独进行处理&#xff0c;目前最常用的阴影计算技术之一就是Shadow Mapping技术&#xff0c;也就是俗称的阴影映射技术。 2.阴影映射 Shadow Map…

使用Tauri+vite+koa2+mysql开发了一款待办效率应用

&#x1f389;使用Taurivitekoa2mysql开发了一款待办效率应用 &#x1f4dd;项目概述 这是一个基于taurivite的应用&#xff0c;它采用了一些最新的前端技术&#xff0c;包括 Tauri、Vue3、Vite5、koa2 和 mysql。它提供了丰富的效率管理工具。 应用地址&#xff1a;https:/…

excel字符串列的文本合并

excel表有两列&#xff0c;第一列是“姓名”&#xff0c;第二列是“诊断”&#xff0c;有高血压、糖尿病等。我想出一个统计表&#xff0c;统计“姓名”&#xff0c;把某一个姓名的诊断不重复的用、拼接起来&#xff0c;比如“张三”的诊断为“点高血压”、糖尿病。我们可以用T…

轻量级SEO分析工具网站源码去授权

轻量级SEO分析工具网站全新去授权发布&#xff0c;这款工具将助您轻松生成直观、简洁、易于理解的SEO报告&#xff0c;为您的网页排名和表现提供有力支持。 测试环境&#xff1a; Apache PHP 8.0 MySQL 5.7 更新日志 v12.0 – 2024年2月20日 新增功能&#xff1a; 正常运行…

LabVIEW在核磁共振实验室的应用

​核磁共振&#xff08;NMR&#xff09;实验室在进行复杂的核磁共振实验时&#xff0c;需要一个高效、灵活且易于操作的实验控制和数据采集系统。传统的NMR实验系统往往使用专门的硬件和软件&#xff0c;存在系统封闭、扩展性差、维护成本高等问题。为了解决这些问题&#xff0…

【JavaEE】Spring Boot 统一功能处理

一.拦截器使用. 1.什么是拦截器? 拦截器是Spring框架提供的核心功能之⼀, 主要用来拦截用户的请求, 在指定方法前后, 根据业务需要执行预先设定的代码 也就是说, 允许开发人员提前预定义一些逻辑, 在用户的请求响应前后执行. 也可以在用户请求前阻止其执行. 在拦截器当中&am…

Flutter 像素编辑器#05 | 缩放与平移

theme: cyanosis 本系列&#xff0c;将通过 Flutter 实现一个全平台的像素编辑器应用。源码见开源项目 【pix_editor】。在前三篇中&#xff0c;我们已经完成了一个简易的图像编辑器&#xff0c;并且简单引入了图层的概念&#xff0c;支持切换图层显示不同的像素画面。 《Flutt…

Web服务器与Apache(LAMP架构+搭建论坛)

一、Web基础 1.HTML概述 HTML&#xff08;Hypertext Markup Language&#xff09;是一种标记语音,用于创建和组织Web页面的结构和内容&#xff0c;HTML是构建Web页面的基础&#xff0c;定义了页面的结构和内容&#xff0c;通过标记和元素来实现 2.HTML文件结构 <html>…

抖音电商618国货数据:洗护、服饰等受欢迎,活力28环比增长40%

发布 | 大力财经 6月21日&#xff0c;抖音电商发布“抖音商城618好物节”消费数据报告&#xff08;下称“报告”&#xff09;&#xff0c;披露618期间平台全域经营情况及大众消费趋势&#xff0c;其中国货表现亮眼。 本次大促恰逢传统节日端午节&#xff0c;报告显示&#xf…

实验08 软件设计模式及应用

目录 实验目的实验内容一、能播放各种声音的软件产品Sound.javaDog.javaViolin.javaSimulator.javaApplication.java运行结果 二、简单工厂模式--女娲造人。Human.javaWhiteHuman.javaYellowHuman.javaBlackHuman.javaHumanFactory.javaNvWa.java运行结果 三、工厂方法模式--女…

React 扩展

文章目录 PureComponent1. 使用 React.Component&#xff0c;不会进行浅比较2. 使用 shouldComponentUpdate 生命周期钩子&#xff0c;手动比较3. 使用 React.PureComponent&#xff0c;自动进行浅比较 Render Props1. 使用 Children props&#xff08;通过组件标签体传入结构&…

nginx负载均衡案例,缓存知识----补充

负载均衡案例 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near great all on wordpress.* to wp172.16.1.% indentified by 1 at line 1 MariaDB [(none)]>…

iptables(5)常用扩展模块iprange、string、time、connlimit、limit

简介 之前我们已经介绍过扩展模块的简单使用,比如使用-m tcp/udp ,-m multiport参数通过--dports,--sports可以设置连续和非连续的端口范围。那么我们如何匹配其他的一些参数呢,比如源地址范围,目的地址范围,时间范围等,这就是我们这篇文章介绍的内容。 iprange扩展模块…