【C++基础(六)】类和对象(中) --构造,析构函数

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C++初阶之路⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习C++
  🔝🔝


在这里插入图片描述

类和对象-中

  • 1. 前言
  • 2. 构造函数
  • 3. 构造函数的特性
  • 4. 对默认构造函数的理解
  • 5. 对默认构造函数的补充
  • 6. 析构函数
  • 7. 对析构函数的理解
  • 8. 对默认析构函数的理解
  • 9. 总结以及拓展

1. 前言

本章重点:

本篇文章着重讲解类中的
两个默认函数,分别为:
构造函数,析构函数
并且介绍类的六个默认函数
(其他三个在后面章节讲解)

我们平时写数据结构时,比如:栈和队列

经常忘记写或者调用初始化函数
使得栈类中的变量是随机值,易出错

有时忘记调用销毁函数,导致内存泄漏
非常的不方便,不好用!

在这里插入图片描述

于是C++引入了这几个函数
可以有效的解决这些问题!


2. 构造函数

构造函数,顾名思义是用于初始化的函数

特性:

  • 函数名与类名相同
  • 无返回值
  • 对象实例化时自动调用对应的构造函数
  • 构造函数可以重载

需要注意的点:

  • 构造函数是特殊的成员函数
    不能将它与普通函数对比

  • 构造函数的任务是初始化对象
    而不是开辟空间创造对象

举例说明:

 class Date{public:Date(int year, int month, int day)//构造函数{_year = year;_month = month;_day = day;}Date()//无参的构造函数{_year = 1900;_month = 1;_day = 1;}private:int _year;int _month;int _day;};int main()
{Date d1; // 调用无参构造函数Date d2(2023, 7, 24);//调用含参的构造
}

注:构造函数是实例化对象时就调用

对象后面跟一个括号来调用!


3. 构造函数的特性

如果使用者没有显示写构造函数
系统就会自动生成一个默认构造函数

比如:

class Date{public:/*// 如果用户显式定义了构造函数,编译器将不再生成Date(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类中构造函数屏蔽后,代码可以通过编译,因为编译器生成了一个无参的默认构造函数// 将Date类中构造函数放开,代码编译失败,因为一旦显式定义任何构造函数,编译器将不再生成// 无参构造函数,放开后报错:error C2512: “Date”: 没有合适的默认构造函数可用Date d1;return 0;}

对代码的解释:

屏蔽掉自己写的构造函数时
编译器会自动生成一个,d1在
实例化时就会去调用编译器生成的

然而当放开自己写的构造函数后
会报错,因为自己实现的构造函数
没有缺省值,并且d1实例化时没有传参


4. 对默认构造函数的理解

可能你们会疑惑:
既然编译器会自己生成构造函数
那我是不是写不写构造函数都可以了?

带着此疑问引出一个新概念:

内置类型和自定义类型

  • 内置类型是C++语言提供的类型
    比如: int/char类型

  • 自定义类型是用户使用class类
    定义出来的类型,如:Date类(日期类)

这个新概念有什么用?

  • 编译器自动生成的构造函数
    不会处理内置类型,它们是随机值

  • 然而自动生成的构造会处理自定义类型
    它会去调用自定义类型的默认构造

举例说明:

class Time
{
public:Time()//Time类的构造函数{cout << "Time()" << endl;_hour = 0;_minute = 0;_second = 0;}
private:int _hour;int _minute;int _second;
};class Date
{
private:// 基本类型(内置类型)int _year;int _month;int _day;// 自定义类型Time _t;
};

对代码的理解:

Date类没有显示写构造函数
所以编译器会自动生成一个构造函数
此构造函数不会处理内置类型
所以成员变量:
year,month,day都是随机值

然而此构造函数会处理自定义类型
它会去调用Time类的默认构造函数
将成员变量_t初始化


5. 对默认构造函数的补充

你可能会疑惑:上面的代码中
Time类显示写了构造函数
为啥还能被称为默认构造函数被调用?

默认构造函数可以是下面的类别:

  1. 编译器自动生成的默认构造
  2. 显示写的无参的构造函数
  3. 显示写的全缺省的构造函数

请看下面的代码:

class Date
{
public:Date()//默认构造函数{_year = 1900;_month = 1;_day = 1;}Date(int year = 1900, int month = 1, int day = 1)//默认构造函数{_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};

上面两种写法都是默认构造函数!
但是它们不能同时存在
因为当实例化对象时没有传参,系统
不知道是调用全缺省函数还是无参的函数


6. 析构函数

现在我们知道一个对象是怎么被初始化的
那么一个对象又是怎么被销毁的呢?

析构函数的概念:

与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作

析构函数的特性:

  • 析构函数名是在类名前加上字符 ~

  • 析构函数无参数无返回值类型

  • 一个类只有一个析构函数,若未显式定义
    系统会自动生成默认的析构函数

  • 析构函数不能重载!

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

注:析构函数和构造函数一样
是特殊的函数,不能将它与普通函数相比


7. 对析构函数的理解

有了前面构造函数的铺垫
析构函数就容易理解了,和我们想的一样
编译器自动生成的默认析构函数
只处理自定义类型,而内置类型不会管

那你可能会问:

既然默认析构函数不会处理内置类型
那么内置类型是不是不会销毁?

答案是: 不!

内置类型会在对象生命周期结束时
将它在栈区的空间还给操作系统
所以析构函数不处理在栈区的变量
也没有问题

但是有些变量的指针指向堆区
有由动态开辟出来的空间
这份空间不会主动还给操作系统
需要我们手动写析构函数来释放!

请看以下代码:

typedef int DataType;
class Stack
{
public:Stack(size_t capacity = 3)//构造函数{_array = (DataType*)malloc(sizeof(DataType) * capacity);if (NULL == _array){perror("malloc申请空间失败!!!");return;}_capacity = capacity;_size = 0;}~Stack()//析构函数{if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}}
private:DataType* _array;int _capacity;int _size;
};
void TestStack()
{Stack s;
}

这段代码中,存在在堆区申请的空间
所以不能使用编译器默认生成的析构
而是要用自己写的析构函数去free掉
这块堆区的空间


8. 对默认析构函数的理解

和构造函数一样,默认析构函数
会去调用自定义类型的析构函数

在这里插入图片描述

可以用下面这段代码来验证一下:

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;
}

当d的生命周期结束时
系统会自动调用析构函数
而Date类没有显示写析构函数
就会使用编译器自动生成的析构

此析构函数会去调用Time的析构函数
所以屏幕上就会打印:~Time()

在这里插入图片描述


9. 总结以及拓展

构造函数是析构函数是对立的
一个用于初始化,一个用于销毁对象调用
掌握它们对后面类和对象的学习很重要

拓展1:

类的六个默认函数:

在这里插入图片描述

现在已经学了构造和析构函数!


拓展2:

C++11新增内容:

C++11新增了一个功能:

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

例如:

class Time
{
public:Time(){cout << "Time()" << endl;_hour = 0;_minute = 0;_second = 0;}
private:int _hour = 1;//声明的时候给缺省值int _minute = 1;int _second = 1;
};

如果用户没有显示传参
那么hour,minute,second
的值都会初始化为1


🔎 下期预告:拷贝构造函数 🔍

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

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

相关文章

分布式系统的应用程序性能监视工具-skywalking

分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。提供分布式链路日志追踪、剖析、服务网格遥测分析、度量聚合和可视化一体化解决方案。 在应用系统进行实时监控,实现对应用性能管理和故障定位的系统化解决方案中常用的…

爬虫小白-如何辨别是否有cookie反爬案例

目录 一、Cookie介绍二、cookie生成来源区分查找三、如何判断是否有cookie反爬四、来自服务器生成的cookie反爬解决方法五、来自js生成的cookie反爬解决方法 一、Cookie介绍 先推荐该篇文章简单了解Cookie、Session、Token、JWT1、cookie的类型&#xff1a;会话cookie和持久co…

[驱动开发]字符设备驱动应用——点灯

点亮开发板stm32mp157的三盏灯 //头文件 #ifndef __LED_H__ #define __LED_H__//封装GPIO寄存器 typedef struct { volatile unsigned int MODER; // 0x00volatile unsigned int OTYPER; // 0x04volatile unsign…

Linux Day01

目录 一、Linux终端介绍 二、Linux目录介绍 1.目录结构 2.常见目录说明 3.绝对路径与相对路径 4.家目录 一、Linux终端介绍 二、Linux目录介绍 Linux目录&#xff1a;是从根目录"/"开始的 是一棵倒着的树 1.目录结构 2.常见目录说明 目前记住 bin 存放常用命…

跨境独立站如何应对恶意网络爬虫?

目录 跨境出海独立站纷纷成立 爬虫威胁跨境电商生存 如何有效识别爬虫&#xff1f; 技术反爬方案 防爬虫才能保发展 中国出海跨境电商业务&#xff0c;主要选择大平台开设店铺&#xff0c;例如&#xff0c;亚马逊、eBay、Walmart、AliExpress、Zalando等。随着业务的扩大&…

使用springboot进行后端开发100问

properties和yaml文件怎么互转 安装插件 properties文件和yaml文件区别 properties 文件通过“.”和“”赋值&#xff0c;值前不加空格&#xff0c;yaml通过“:”赋值&#xff0c;值前面加一个空格&#xff1b;yaml文件缩进用空格&#xff1b; properties只支持键值对&#x…

Ubuntu下打开QtCreator环境变量LD_LIBRARY_PATH与终端不一致

问题描述&#xff1a; 在unbuntu下使用QtCreator编译、运行程序时&#xff0c;总是出现XXX.so: cannot open shared object file: No such file or directory这类问题&#xff0c;但是在终端中编译或者运行程序则不会出现这些问题。在网上查了好久才明白QtCreator在打开时&…

逻辑漏洞原理及实战

前言 作者简介&#xff1a;不知名白帽&#xff0c;网络安全学习者。 博客主页&#xff1a;不知名白帽_网络安全,CTF,内网渗透-CSDN博客 网络安全交流社区&#xff1a;https://bbs.csdn.net/forums/angluoanquan 目录 逻辑漏洞基础 概述 分类 URL跳转漏洞 概述 危害 漏洞…

51单片机串口

该部分的笔记来自视频教程链接https://www.bilibili.com/video/BV1bt4y197NR/?spm_id_from333.788&vd_sourceb91967c499b23106586d7aa35af46413 一、51单片机串口基础介绍 一般的应用层的协议中采用和校验或CRC校验&#xff0c;而奇偶校验还是解决基本通信中的帧格式中的…

Eclipse整合tomcat时要注意的几点

Eclipse整合tomcat时要注意的几点 1、安装目录及jdk 2、参数配置 注意&#xff1a;Arguments的配置&#xff0c;日志输出文件目录及java内存大小设置等&#xff0c;如下&#xff1a; -Dcatalina.base"E:\apache-tomcat-7.0.52" -Dcatalina.home"E:\apache-tomc…

无符号数和有符号数的“bug”

1. 起因 在实现kmp算法时&#xff0c;出现了诡异的现象&#xff0c;看下面的代码&#xff1a; int KMP (const char *s, const char *t) {int lenS strlen (s);int lenT strlen (t);int next[lenT];get_next (next, t);int i 0;int j 0;while (i < lenS && j …

程序化广告还有未来么?——程序化领域变化的底层逻辑和反思

三、近几年程序化广告领域的变化底层逻辑是什么呢&#xff1f; 当前国内程序化生态的状态&#xff0c;更像是希腊的古典时代&#xff1a;古希腊时代的城邦高度繁荣的时期。很多人可能对古希腊城邦没有概念&#xff0c;我们解释一下&#xff1a; 所谓城邦就是城市国家&#xff0…

涵子来信——自己的电脑——谈谈想法

大家好&#xff1a; 上一次谈论了苹果的那些事&#xff0c;今天我们来聊聊电脑。 我的第一台电脑现在成了这样子&#xff1a; 很多人以为是我自己拆了电脑做研究&#xff0c;其实是我的第一台电脑&#xff0c;真的坏了。 2021年&#xff0c;我有了属于我自己的第一台电脑&am…

链表 --- C语言实现

本篇文章来详细介绍一下数据结构中的链表。 目录 1.链表的概念及结构 2.链表的分类 3.单链表的实现 4.链表的面试题 5.双向链表的实现 6.顺序表和链表的区别 1.链表的概念及结构 概念&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素…

【HTML5】拖放详解及实现案例

文章目录 效果预览代码实现 效果预览 代码实现 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>一颗不甘坠落的流星</title><style>#div1,#div2 {float: left;width: 100px;height: 27px;margin: 10px;paddin…

关于 Qt在windows使用mingw32编译器时从Qt5.9切换至Qt5.12出现“C2001:常量中有换行符“不修改编码 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/131901444 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软…

Git简介与工作原理:了解Git的基本概念、版本控制系统和分布式版本控制的工作原理

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

day33哈希表

1.哈希表 常见的哈希表分为三类&#xff0c;数组&#xff0c;set&#xff0c;map&#xff0c;C语言的话是不是只能用数组和 2.例题 题目一&#xff1a; 分析&#xff1a;题目就是判断两个字符串出现的次数是否相同&#xff1b; 1&#xff09;哈希表26个小写字母次数初始化为0&…

RB-tree(红黑树)详解

RB-tree(红黑树) 红黑树的规则如下&#xff1a; 1.每个节点不是红色就是黑色 2.根节点为黑色 3.如果节点为红色&#xff0c;那么它的子节点必须为黑色 4.任何一个节点到NULL&#xff08;树的尾端&#xff09;的任何路径所包含的黑节点个数相同 简而言之就是每个路径的黑色节点数…

模拟量输出FC S_RTI(信捷C语言源代码)

模拟量输出FC SCL源代码请查看下面博客: PLC模拟量输出 模拟量转换FC S_RTI_博途模拟量转换指令_RXXW_Dor的博客-CSDN博客1、本文主要展示西门子博途模拟量输出转换的几种方法, 方法1:先展示下自编FC:计算公式如下:intput intput Real ISH Real //工程量上限 ISL Real //工…