当前位置: 首页 > news >正文

C++类和对象:构造函数和析构函数

目录

一. 类的六个默认成员函数

二. 构造函数

2.1 什么是构造函数

2.2 编译器自动生成的默认构造函数 

2.3 构造函数的特性总结

三. 析构函数

3.1 什么是析构函数

3.2 编译器自动生成的析构函数

3.3 析构函数的特性总结


一. 类的六个默认成员函数

对于任意一个C++类,如果用户不定义任何成员函数,那么编译器就会自动生成6个默认成员函数。当然,这6个成员函数也可以由用户自主定义,如果用户自主定义了,那么系统就不会自动生成。这6个默认成员函数包括:构造函数、析构函数、拷贝构造函数、赋值重载函数、对普通对象和const对象的取地址重载函数。

图1.1  C++类的6个默认成员函数

二. 构造函数

2.1 什么是构造函数

构造函数在定义类对象是由编译的自动调用,用于初始化类的成员变量。构造函数是一种十分特殊的成员函数,它没有返回值,它的函数名与类名相同。

任何一个类都不能没有默认构造函数,否则这个类就是非法的,在用这个类初始化对象时编译器会报错。默认构造函数,就是不需要参数就可以调用的构造函数,默认构造函数有三种可能的形式:

  1. 无参数
  2. 全缺省参数
  3. 由编译器自动生成的构造函数

演示代码2.1定义了一个日期类,并定义了一个全缺省的构造函数,这里由于用户自定义了构造函数,所有编译器不会生成默认构造函数。此外,还应当明确,构造函数是支持重载的,Date(int year = 1, int month = 1, int day = 1)可以被拆分为一个无参的构造函数Date()和一个不存在确实参数的构造函数Date(int year, int month, int day)。

演示代码2.1:

class Date  //日期类
{
public:Date(int year = 1, int month = 1, int day = 1)  //自定义默认构造函数{_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}private:int _year;int _month;int _day;
};int main()
{//定义类对象,调用默认构造函数Date d1;  //Date(1, 1, 1)Date d2(2023, 2, 26);  //Date(2023, 2, 26)d1.Print();  //1-1-1d2.Print();  //2023-2-26return 0;
}
图2.1 演示代码2.1的运行结果

2.2 编译器自动生成的默认构造函数 

当用户不自定义默认构造函数时,编译器就会自动生成默认构造函数,编译的自动生成的构造函数进行的工作为:

  1. 对于内置类型成员变量,不进行初始化
  2. 对于自定义类型成员变量,调用自定义类型成员变量的默认构造函数

其中,内置类型指int、char、double、float、指针、内置类型数组等C/C++自带的数据类型,自定义类型指使用struct/class定义的类或结构体数据类型。

为了验证编译器自动生成的构造函数所完成的功能,在演示代码2.2中定义了一个Date类和一个Time类,在Date类中不自定义构造函数,在Time类中定义默认构造函数将Time中的成员变量全部初始化为1,Date类中包括3个内置类型成员变量和1个Time类类型的成员变量。对程序进行调试,可见定义好的Date类对象d1中的内置类型成员变量都是随机值,而d1中的类对象t的成员变量都变变为了1。这就证实了上面对编译的自动生成的构造函数进行的工作的讲述的正确性。

演示代码2.2:

class Time
{
public:Time(int hour = 1, int minute = 1, int second = 1)  //自定义默认构造函数{_hour = hour;_minute = minute;_second = second;}private:int _hour;int _minute;int _second;
};class Date
{
private:int _year;int _month;int _day;Time t;
};int main()
{Date d1;  //定义类对象,调用编译器自动生成的默认构造函数return 0;
}
图2.2  演示代码2.2的调试界面

我们可以认为默认构造函数不对内置类型成员变量做任何处理是C++的一个缺陷。为了弥补这一缺陷, C++11允许在定义类是显示的声明内置类型成员变量的初值。如演示代码2.3所示,Date类中的三个成员变量都被赋默认初值1。

演示代码2.3:

class Date
{
public:void Print(){cout << _year << "-" << _month << "-" << _day << endl;}private:int _year = 1;int _month = 1;int _day = 1;    //三个内置类型的成员变量的默认初值都为1(C++11)
};int main()
{Date d;d.Print();  //1-1-1return 0;
}

2.3 构造函数的特性总结

  1. 构造函数是特殊的成员函数,函数名与类名相同,无返回值。
  2. 构造函数在对象实例化时由编译器自主调用,无需用户手动调用。
  3. 构造函数可以重载。
  4. 如果用户不显示定义构造函数,那么编译器就会生成默认的构造函数。

三. 析构函数

3.1 什么是析构函数

析构函数的功能与构造函数相反,在类对象生命周期结束时,由编译器自动调用,完成对类对象的资源清理工作,析构函数的函数名为:~类名。

析构函数可以由用户自身定义,也可以由编译器自主生成。当拥护显示的定义了析构函数时,编译器不自动生成析构函数,但当用户不显示的定义析构函数时,编译器会自动生成默认的析构函数。

析构函数没有参数、没有返回值。

演示代码3.1定义了一个简易的栈类Stack,其中定义了三个成员变量:int* _a -- 存储栈数据的数组、int _top -- 栈顶位置下标、int _capacity -- 栈容量,还定义了四个成员函数:Stack -- 栈初始化函数(构造函数)、Push -- 压栈函数、Print -- 栈中数据打印函数、~Stack -- 栈销毁函数(析构函数)。在~Stack函数中释放了动态开辟的内存。

在主函数中,我们创建了一个栈类对象S,程序的运行结果表明,构造函数和析构函数先后被调用。

演示代码3.1:

class Stack
{
public:Stack(int capacity = 3)  //构造函数,初始化栈,类实例化时自动调用{cout << "Stack()" << endl;_a = (int*)malloc(capacity * sizeof(int));  //为栈数组动态开辟内存空间if (nullptr == _a){cout << "malloc fail" << endl;exit(-1);}_capacity = capacity;_top = 0;}void Push(int x)  //压栈函数,x为压入数据{if (_top == _capacity)  //检查栈是否已满{int* tmp = (int*)realloc(_a, (_capacity * 2) * sizeof(int));  //开辟新的内存空间if (tmp == nullptr){cout << "realloc fail" << endl;}_a = tmp;_capacity *= 2;}_a[_top++] = x;}void Print()  //栈中数据打印函数{for (int i = 0; i < _top; ++i){cout << _a[i] << " ";}cout << endl;}~Stack()  //析构函数,在对象生命周期结束时自动调用{cout << "~Stack()" << endl;free(_a);  //释放栈空间_a = nullptr;_top = _capacity = 0;}private:int* _a;  //存储栈数据的数组int _top;  //栈顶下标int _capacity;  //栈容量
};int main()
{Stack S;  //类实例化,调用默认构造函数S.Push(1);S.Push(2);S.Push(3);S.Push(4);S.Push(5);  //将1、2、3、4、5压入栈中S.Print();  //打印栈中数据return 0;  //对象生命周期结束,调用析构函数
}
图3.1  演示代码3.1的运行结果

3.2 编译器自动生成的析构函数

如果用户不显示定义析构函数,则编译器会生成默认的析构函数,编译器自动生成的析构函数所执行的操作与编译器自动生成的构造函数类似:

  1. 对于内置类型成员变量,不做任何处理。
  2. 对于自定义类型成员变量,去掉它的析构函数。

演示代码3.2定义了一个名为TwoStack的类,其中包含两个Stack类的自定义类型成员变量S1和S2,在主函数中对类进行实例化,创建对象ts,在ts创建和销毁时都调用Stack的默认构造函数和析构函数。

演示代码3.2:

class TwoStack
{
private:Stack S1;Stack S2;
};int main()
{TwoStack st;  //类实例化,调用默认构造函数return 0;  //对象生命周期结束,调用析构函数
}
图3.2  演示代码3.2运行结果

问题:什么时候可以使用编译器自动生成的析构函数,什么时候必须显示定义析构函数? 

  • 当类中的成员变量仅在栈区占用内存空间时,类对象的生命周期结束是成员变量所占用的空间自动被释放,不需要析构函数执行额外的操作,如日期类Date,就不需要自定义析构函数。
  • 当类的成员变量执行堆区开辟的某一块空间时,如通过malloc动态开辟了内存空间,就需要显示的定义析构函数来进行资源清理,如Stack类就不能使用编译器自动生成的析构函数。

3.3 析构函数的特性总结

  1. 析构函数的函数名是在类名前面加~。
  2. 析构函数无参数、无返回值。
  3. 析构函数在类对象生命周期结束时由编译器自主调用。
  4. 一个类有且只有一个析构函数,要么由用户显示定义,要么由编译器自动生成。
  5. 如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如
    Date类;有资源申请时,一定要写,否则会造成资源泄漏,比如Stack类。

相关文章:

C++类和对象:构造函数和析构函数

目录 一. 类的六个默认成员函数 二. 构造函数 2.1 什么是构造函数 2.2 编译器自动生成的默认构造函数 2.3 构造函数的特性总结 三. 析构函数 3.1 什么是析构函数 3.2 编译器自动生成的析构函数 3.3 析构函数的特性总结 一. 类的六个默认成员函数 对于任意一个C类&…...

【Stata】从入门到精通.零基础小白必学的教程,一学就fei

视频教程移步&#xff1a;https://www.bilibili.com/video/BV1hK4y1d714/?p4&spm_id_frompageDriver&vd_sourcecc8074e9c81a225f214226065db53d32P3 第二讲 Stata处理数据全流程&#xff08;上&#xff09; P3 - 01:37&#xfeff;内置数据 file example datasets使用…...

【RuoYi优化】调整JVM启动内存

📔 笔记介绍 大家好,千寻简笔记是一套全部开源的企业开发问题记录,毫无保留给个人及企业免费使用,我是作者星辰,笔记内容整理并发布,内容有误请指出,笔记源码已开源,前往Gitee搜索《chihiro-notes》,感谢您的阅读和关注。 作者各大平台直链: GitHub | Gitee | CSD…...

[架构模型]MVC模型详细介绍,并应用到unity中

简介&#xff1a; MVC模式是一种软件架构模式&#xff0c;它将应用程序分为三个主要部分&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和控制器&#xff08;Controller&#xff09;。MVC模式的目标是实现应用程序的松耦合&#xff0c;以便…...

?? JavaScript 双问号(空值合并运算符)

?? JavaScript 双问号&#xff08;空值合并运算符) 一、简述 在网上浏览 JavaScript 代码时或者学习其他代码时&#xff0c;可能会发现有的表达式用了两个问号&#xff08;??&#xff09;如下所示&#xff1a; let username; console.log(username ?? "Guest"…...

作业2.25----通过操作Cortex-A7核,串口输入相应的命令,控制LED灯进行工作

1.通过操作Cortex-A7核&#xff0c;串口输入相应的命令&#xff0c;控制LED灯进行工作 例如在串口输入led1on,开饭led1灯点亮 2.例如在串口输入led1off,开饭led1灯熄灭 3.例如在串口输入led2on,开饭led2灯点亮 4.例如在串口输入led2off,开饭led2灯熄灭 5.例如在串口输入led…...

0101基础概念-图-数据结构和算法(Java)

文章目录1 图1.1 定义1.2 4种图模型2 无向图2.1 定义2.2 术语后记1 图 1.1 定义 图是一种非线性的数据结构&#xff0c;表示多对多的关系。 图&#xff08;Graph&#xff09;是由顶点的有穷非空集合和顶点之间边的集合组成&#xff0c;通常表示为&#xff1a;G(V, E)&#xf…...

Linux基础命令和工具使用详解

Linux基础命令和工具使用详解一、grep搜索字符二、find查找文件三、ls 显示文件四、wc命令计算字数五、uptime机器启动时间负载六、ulimit用户资源七、curl http八、scp远程拷贝九、dos2unix和unix2dos十、sed 行处理10.1、简单模式10.2、替换模式十一、awk 列处理11.1、打印某…...

一个好的python文件可以有几种用途?

大家好鸭&#xff01;我是小熊猫~ 这次来带大家浅浅回顾一点python小知识~ 源码资料电子书:点击此处跳转文末名片获取 python文件总共有两种用途&#xff1a; 一种是执行文件另一种是被当做模块导入 编写好的一个python文件可以有两种用途&#xff1a; 1. 脚本&#xff0c;…...

HDFS优化

单节点多块磁盘数据均衡 生成HDFS块均衡计划 hdfs diskbalancer -plan node1 执行均衡计划,node1.plan.json均衡计划文件 hdfs diskbalancer -execute node1.plan.json 查看当前均衡任务的执行情况 hdfs diskbalancer -query node1 取消均衡任务hdfs diskbalancer -cancel nod…...

行测-判断推理-图形推理-样式规律-黑白运算

黑白元素个数不同&#xff0c;优先考虑黑白运算白白白黑黑白黑白黑选A考试时&#xff0c;这种题不要先把规律全部推出来&#xff0c;再去做题&#xff0c;太慢了直接看要推的图&#xff0c;通过排除法选答案黑白元素个数不同&#xff0c;优先考虑黑白运算白白白黑黑白黑白黑选B…...

java+springboot+vue高校学生医疗保险管理系统

医保管理系统是对与职工健康息息相关的档案进行的系统化、自动化的管理&#xff0c;主要是对职工办理的医疗保险的管理&#xff0c;本系统能够很好的适应社会的需求&#xff0c;最大化的为城镇职工提供服务。医疗保险是国家社会保障体系的重要组成部分&#xff0c;也是社会保险…...

[已解决] AHK 映射 ESC 延迟 500 ms 的严重问题

问题描述 今天发现一个重大bug&#xff0c;我竟然用了一年多都不知道&#xff01; CapsLock::Esc 我的 ahk 脚本将 capslock 映射为 esc&#xff0c;但这在vim环境中&#xff0c;估算响应 500ms。 也就说按下 caps 键&#xff0c;还要等一会&#xff0c;才进入normal模式 如果…...

QML state详解

1.state简介 changes&#xff08;list<Change>&#xff09;&#xff1a;保存当前State下的多个Change对象,比如PropertyChanges、StateChangeScript、ParentChange等。 extend&#xff08;string&#xff09;&#xff1a;表示该状态要在哪个State的基础上进行扩展,当一个…...

一起Talk Android吧(第五百零六回:如何调整组件在约束布局中的角度)

文章目录背景介绍相关属性使用方法示例程序各位看官们大家好&#xff0c;上一回中咱们说的例子是"如何调整组件在约束布局中的大小",这一回中咱们说的例子是"如何调整组件在约束布局中的角度"。闲话休提&#xff0c;言归正转&#xff0c; 让我们一起Talk A…...

微信投票-课后程序(JAVA基础案例教程-黑马程序员编著-第七章-课后作业)

【实验7-5】 微信投票 【任务介绍】 1.任务描述 如今微信聊天已经普及到几乎每一个人&#xff0c;在聊天中&#xff0c;经常会有人需要帮忙在某个APP中投票。本案例要求编写一个模拟微信投票的程序&#xff0c;通过在控制台输入指令&#xff0c;实现添加候选人、查看当前投票…...

duboo+zookeeper分布式架构入门

分布式 dubbo Zookeeper 分布式系统就是若干独立计算机的集合&#xff08;并且这些计算机之间相互有关联&#xff0c;就像是一台计算机中的C盘F盘等&#xff09;&#xff0c;这些计算对于用户来说就是一个独立的系统。 zookeeper安装 下载地址&#xff1a;Index of /dist/z…...

黑盒测试用例设计方法-等价类划分法

目录 一、等价类的作用 二、等价类的分类 三、等价类的方法 四、等价类的原则 五、按照测试用例的完整性划分等价类 六、等价类步骤 七、案例 一、等价类的作用 为穷举测试设计测试点。 穷举&#xff1a;列出所有的可能情况&#xff0c;对其一一判断。 测试点&#x…...

4.OCR文本识别Connectionist Temporal Classification(CTC)算法

文章目录1.基础介绍2.Connectionist Temporal Classification(CTC)算法2.1 什么是Temporal Classification2.2 CTC问题描述2.2关于对齐2.3 前向后向算法2.4 推理时3.pytorch中的CTCLOSS参考资料欢迎访问个人网络日志&#x1f339;&#x1f339;知行空间&#x1f339;&#x1f3…...

误删了Ubuntu/Linux的一些默认用户目录怎么办?

用户目录&#xff1a;指位于 $HOME 下的一系列常用目录&#xff0c;例如 Documents&#xff0c;Downloads&#xff0c;Music&#xff0c;还有 Desktop等。本文不是讲如何恢复原有目录及其重要文件&#xff0c;适用于仅恢复目录功能一&#xff1a;仅恢复个别目录如误删了Desktop…...

ArXiv简介以及论文提交

arXiv网站简介 arXiv是一个收集物理学、数学、计算机科学、生物学与数理经济学的论文预印本的网站。其中arXiv发音同“archive”&#xff0c;因为“X”代表希腊字母 &#xff0c;国际音标为[kai]。它于1991年8月14日成立&#xff0c;现由美国康奈尔大学维护。 ——维基百科 对…...

pytorch学习

目录如下&#xff1a; pytorch常用操作 pytorch 常用操作 pytorch 的 detach()函数 1. 什么是detach()函数 我们在将输出特征矩阵进行存储的时候&#xff0c;经常需要将torch.Tensor类型的数据转换成别的如numpy类型的数据&#xff0c;但是Tensor类型的数据是会自动计算梯度…...

【OC】块初识

Block简介 Blocks是C语言的扩充功能。可以用一句话来表示Blocks的扩充功能&#xff1a;带有自动变量的匿名函数。 匿名函数 所谓匿名函数就是不带有名称的函数。C语言的标准不允许存在这样的函数。例&#xff1a; int func(int count);它声明了名称为func的函数。下面的源代…...

3-2 创建一个至少有两个PV组成的大小为20G的名为testvg的VG

文章目录1. 在vmware添加多块20G的硬盘&#xff0c;并创建分区2. 创建一个至少有两个PV组成的大小为20G的名为testvg的VG&#xff0c;要求PE大小为16M&#xff0c;而后在卷组中创建大小为5G的逻辑卷testlv;挂载至/users目录3. 新建用户archlinux,要求其家目录为/users/archlinu…...

【密码学】 一篇文章讲透数字证书

【密码学】 一篇文章讲透数字证书 数字证书介绍 数字证书是一种用于认证网络通信中参与者身份和加密通信的证书&#xff0c;人们可以在网上用它来识别对方的身份。 我们在上一篇博客中介绍了数字签名的作用和原理&#xff0c;数字签名可以防止消息被否认。有了公钥算法和数字签…...

Linux 操作系统原理 — 内存管理 — 虚拟地址空间(x86 64bit 系统)

目录 文章目录目录虚拟地址格式与内核页表&#xff08;四级页表&#xff09;虚拟地址格式与内核页表&#xff08;四级页表&#xff09; 在 x86 64bit 系统中&#xff0c;可以描述的最长地址空间为 2^64&#xff08;16EB&#xff09;&#xff0c;远远超过了目前主流内存卡的规格…...

C语言深入知识——(2)指针的深入理解

1、字符指针 &#xff08;1&#xff09;字符指针的普通用法 char a A; char* pa &a;但是一般来说字符指针很少这么用……更多是拿来存储一个字符串 &#xff08;2&#xff09;字符串的两种存储以及区别 现在有了两种存储数组的方法 ①一个是使用char类型数组存储②另外…...

Git使用笔记

分支branch切换到另一个分支git checkout 你要切换到的分支的名字git checkout master将本地的这个分支branch1和gitee上的branch1进行合并&#xff08;本地的branch1有的&#xff0c;gitee上branch1没有的增加上去&#xff09;git merge branch1git merge 分支的名字查看本地是…...

数据库管理-第五十八期 倒腾PDB(20230226)

数据库管理 2023-02-26第五十八期 倒腾PDB1 克隆本地PDB2 没开归档总结第五十八期 倒腾PDB 其实本周过的不大好&#xff0c;连着两天熬夜&#xff0c;一次是割接一次是处理ADG备库的异常&#xff0c;其实本周有些内容是以前处理过的问题&#xff0c;到了周末还肚子痛。哎… 1…...

我看谁还敢说不懂git

文章目录一、Git介绍1.1、Git的作用1.2、Git的理念1.3、Git的特点1.4、Git对比SVN二、Git的概念2.1、Git基础概念三、Git的基本操作3.1、使用Git管理一个代码仓库的流程3.2、Git常用命令介绍四、Git状态的变化五、Git安装和配置5.1、Git的安装5.2、Git的配置六、Git的高级操作6…...

wordpress如何搭建网站/域名免费注册0元注册

flutter学习(5) GridView Gridview是网格布局 文章目录flutter学习(5) GridView一.GridView常用属性二.GridView.count 实现网格布局三.GridView.builder实现网格布局一.GridView常用属性 二.GridView.count 实现网格布局 看这个 import package:flutter/material.dart; import…...

电子商务企业网站设计/google网站登录入口

补题链接&#xff1a;https://ac.nowcoder.com/acm/contest/11255/J 题解可参考此处&#xff1a; https://www.cnblogs.com/lipoicyclic/p/15062880.html 对于a数组: x1, x2, x3...xn 对于b数组: y1, y2, y3...ym 求W矩阵时&#xff0c;要对b数组的每一项都加一次x1,x2,x3..…...

做网站导航怎么调整大小/南京seo按天计费

1. 电商网站里都少不了减库存的操作&#xff0c;当然什么时候减各有各的处理&#xff0c;有的下单就减&#xff0c;有的发起支付就减少&#xff0c;有的支付完成后回调时减。对于这个减库存的时间点&#xff0c;因产品而已&#xff0c;比如秒杀类必须下单就减。 减库存时就不可…...

网站首页布局设计原理/网站建设公司哪家好

文章目录1.基础知识1.1.常规命令1.2.重定向符号,管道符号,通配符号&#xff0c;&&符号1.3.vim文本编辑器1.4.定时任务1.5.防火墙firewall-cmd命令1.6.scp远程上传下载文件2.查询服务器硬件信息3.systemctl服务管理命令4.资源监控命令4.1.查看系统的负载信息4.2.查看内存…...

网站开发建设/厦门seo排名优化方式

OpenMP --- 线程同步 1. 引言 在OpenMP中&#xff0c;线程同步机制包括互斥锁同步机制和事件同步机制。 2. 互斥锁同步 互斥锁同步的概念类似于Windows中的临界区&#xff08;CriticalSection&#xff09;以及Windows和Linux中的Mutex以及VxWorks中的SemTake和SemGive&#xff…...

有哪些图片设计网站有哪些问题/百度推广登录入口登录

目录PLL1和PLL1控制器PLL2和PLL2控制器CSL的使用本文主要介绍TMS320C6455的时钟相关的内容&#xff0c;参考文档为&#xff1a; SPRS276M - TMS320C6455 Fixed-Point Digital Signal ProcessorSPRUE56 - TMS320C645x DSP Software-Programmable Phase-Locked Loop (PLL) Contr…...