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

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

当然不是,任何类在什么都不写的情况下,编译器会自动生成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.mzph.cn/bicheng/34807.shtml

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

相关文章

食品供应链管理商城系统的设计、实现和代码

上线食品供应链管理商城系统的设计与实现是一项复杂且重要的任务&#xff0c;它不仅涉及到技术层面的具体实现&#xff0c;还包括业务流程的优化和用户体验的提升。本文将从系统设计、功能模块、技术选型以及实现步骤等方面进行详细探讨。 ### 系统设计 在设计食品供应链管理…

使用 PHP 开发网络爬虫和数据抓取工具的技巧

使用 PHP 开发网络爬虫和数据抓取工具的技巧 网络爬虫是在互联网上自动获取信息的程序&#xff0c;是很多数据分析和挖掘任务的必备工具。PHP是一种广泛使用的脚本语言&#xff0c;具有易学易用、灵活性高的特点&#xff0c;非常适合用来开发网络爬虫和数据抓取工具。本文将介…

从单一到多元:EasyCVR流媒体视频汇聚技术推动安防监控智能升级

随着科技的飞速发展&#xff0c;视频已成为我们日常生活和工作中的重要组成部分。尤其在远程办公、在线教育、虚拟会议等领域&#xff0c;视频的应用愈发广泛。为了满足日益增长的视频需求&#xff0c;流媒体视频汇聚融合技术应运而生&#xff0c;它不仅改变了传统视频的观看和…

消息队列 有序 消费模式 主题 分区 高可用 持久 日志 崩溃恢复 事务 重试投递 崩溃最多丢失多少数据 日志模式

有序 消费模式 主题 分区 高可用 持久 日志 崩溃恢复 事务 重试投递 崩溃最多丢失多少数据 日志模式 延迟投递 1、把多条消息合并成一个批次等同于一次提交一条消息&#xff1b; 2、发送消息前要打印日志&#xff0c;确保消息丢失了也能在日志中找到。 kafka java sdk 在 Ap…

第二天的课根本跟不上啊 难难难啊

编程实现三个数求最大 编程实现求解一元二次方程 传参问题 直接使用返回值 复制控制 复制控制是指在C中控制对象复制行为的机制&#xff0c; 包括拷贝构造函数&#xff08;copy constructor&#xff09;、 赋值操作符&#xff08;copy assignment operator&#xff09;、 …

mysql workbench使用schema视图导出表和列结构到excel

目的&#xff1a;导出所有表和列的名字和注释 很多时候没有正规的数据库文档&#xff0c;为了快速交流啊&#xff0c;需要一个快捷的基础。数据库建表的时候可能有注释&#xff0c;也可能没有注释。有当然好&#xff0c;查看注释就能清楚很多&#xff0c;没有的话最好一个一个补…

零基础如何制作一个GIS可视化大屏?免费无难度!

一.GIS是什么&#xff1f; GIS&#xff08;地理信息系统&#xff09;开发是一种利用计算机技术对地理信息进行处理、分析、存储和展示的技术。GIS开发可以应用在很多领域&#xff0c;如城市规划、环境保护、交通管理、农业生产等。 二.如何将GIS与数字孪生结合起来&#xff1f…

【面试题】多线程

目录 什么是线程&#xff1f;它与进程的区别是什么&#xff1f;解释一下并行与并发的区别。简述线程安全的概念&#xff0c;并举例说明。如何实现线程同步&#xff1f;有哪些常见的同步机制&#xff1f;在Java中&#xff0c;如何创建线程&#xff1f;谈谈继承Thread类与实现Run…

Verilog的逻辑系统及数据类型(二):参数和参数重载

目录 3.参数&#xff08;parameters)3.1 参数重载&#xff08;overriding)3.2 参数重载举例 微信公众号获取更多FPGA相关源码&#xff1a; 3.参数&#xff08;parameters) 用参数声明一个可变常量&#xff0c;常用于定义延时及宽度变量。参数定义的语法&#xff1a;paramete…

安卓应用开发学习:获取经纬度及地理位置描述信息

前段时间&#xff0c;我在学习鸿蒙应用开发的过程中&#xff0c;在鸿蒙系统的手机上实现了获取经纬度及地理位置描述信息&#xff08;鸿蒙应用开发学习&#xff1a;手机位置信息进阶&#xff0c;从经纬度数据获取地理位置描述信息&#xff09;。反而学习时间更长的安卓应用开发…

adb remount fails - mount: ‘system‘ not in /proc/mounts 解决办法

mount -o rw,remount /挂载根 mount -o ro,remount /将状态重置为“ro” 以下是我个人的一些话 我热衷于在网络上分享我遇到的问题和解决方案。如果你有任何问题或需要帮助&#xff0c;欢迎留言交流&#xff0c;在共同学习的道路上一起进步。我很高兴结识那些在学习上积极进取…

常用框架-Spring Boot

常用框架-Spring Boot 1、Spring Boot是什么?2、为什么要使用Spring Boot?3、Spring Boot的核心注解是哪个?它主要由哪几个注解组成的?4、有哪些运行Spring Boot的方式?5、如何理解 Spring Boot 中的Starters?6、有哪些常见的Starters?7、如何在Spring Boot启动的时候运…

【WEB】关于react的WEB应用中使用React Developer Tools便捷快速查看元素数据

1、往扩展工具中添加React Developer Tools的扩展包 2、检查是否生效&#xff0c;如下图&#xff1a; 可以看到右上角多出来一个Components的tab选项&#xff0c;就是成功了

数据校验(JSR303、SpringBoot、自定义注解)

在一个项目中&#xff0c;不仅前端要对用户输入的数据进行校验&#xff0c;避免发送不必要的请求&#xff0c;而且后端也要对数据进行对应的校验&#xff0c;因为操作不都是通过页面过来的。 前端 不是很了解 正则表达式 配合各种组件使用 后端 这里以Java为例&#xff0…

winform 限制TextBox中只能输入正整数

txt_n是文本框的名字 private void txt_n_KeyPress(object sender, KeyPressEventArgs e){if (e.KeyChar ! \b)//这是允许输入退格键 {int len txt_n.Text.Length;if (len < 1 && e.KeyChar 0){e.Handled true ;}else if ((e.KeyChar < 0) || (e.KeyChar >…

WebStorm 环境配置带@符号的相对路径穿透

在使用WebStorm 环境开发web页面项目时有时想快速查看页面的引用代码&#xff0c;只能手工找到引入文件路径&#xff0c;这很不方便&#xff0c;只需通过配置webStorm单击打开。 1 使用符号相对路径&#xff0c;在默认情况下没有配置环境是无法打开&#xff0c;如下图&#xf…

AI全栈之coze的logo生成

前言 前几日体验了国产的AI-Agents产品coze 它是一种能够自主执行任务、与环境进行交互并根据所获取的信息做出决策和采取行动的软件程序 并且可以自己去创建属于自己的AIBot&#xff0c;还是很有意思的&#xff0c;大家可以去体验体验 在体验过程中&#xff0c;我发现在创…

适合爬虫开发用的性价比高的代理推荐

在爬虫开发过程中&#xff0c;使用代理可以有效地隐藏爬虫的真实来源&#xff0c;并绕过一些可能对爬虫设置的限制。然而&#xff0c;市面上的代理服务众多&#xff0c;选择一款性价比高且适合爬虫开发的代理服务显得尤为重要。以下是一些适合爬虫开发用的性价比比较高的代理推…

Linux操作系统进程同步的几种方式及基本原理

1&#xff0c;进程同步的几种方式 1.1信号量 用于进程间传递信号的一个整数值。在信号量上只有三种操作可以进行&#xff1a;初始化&#xff0c;P操作和V操作&#xff0c;这三种操作都是原子操作。 P操作(递减操作)可以用于阻塞一个进程&#xff0c;V操作(增加操作)可以用于…