C++——类和对象(构造函数与析构函数)

news2024/9/26 1:20:49

构造函数与析构函数

本章思维导图:

在这里插入图片描述

注:本章思维导图对应的Xmind文件和.png文件都已导入到”资料“中

1. 构造函数

在这里插入图片描述

以前,我们写一个Date类一般是这么写的:

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

private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	d1.Init(2023, 10, 30);

	return 0;
}

可以看到,我们每实例化一个Date对象,都要调用一次Init函数来对对象进行初始化,着是有点不方便的。

因此,为了方便初始化对象这一操作,C++有了构造函数这一概念

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

1.1 构造函数的声明和定义

我们规定:

  • 构造函数没有返回值(不需要写void
  • 构造函数的函数名与类名相同
  • 构造函数支持函数重载
  • 构造函数可以没有形参,形参可以都是缺省参数,也可以不是缺省参数

例如,对于Date类的构造函数,我么可以这样写:

class Date
{
public :
	//方式一:
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//方式二:
	Date()
	{
		_year = 2023;
		_month = 10;
		_day = 30;
	}
	//方式三:
	Date(int year = 2023, int month = 10, int day = 30)
	{
		_year = year;
		_month = month;
		_day = day;
	}

private:
	int _year;
	int _month;
	int _day;
};

一般建议将构造函数的形参设置为全缺省参数

1.2 默认构造函数

如果自己不写构造函数,那么系统就会自动生成一个构造函数,即默认构造

例如:

class Date
{
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1;

	return 0;
}

执行过后,对象d1就会变成:

在这里插入图片描述

可以看到,d1里的三个成员变量仍是随机值

那是不是可以说,系统默认生成的默认构造就没有一点价值呢?

以前我们做过一道题——《两个栈实现队列》,现在我们可以就这一道题定义两个类StackMyQueue

class Stack
{
public:
	Stack(int capacity = 3)
	{
		_capacity = capacity;
		_a = (int*)malloc(sizeof(int) * _capacity);
		_top = 0;
	}

	//这只是一个示例代码,其他功能不做展示
private:
	int* _a;
	int _capacity;
	int _top;
};

class MyQueue
{
public:
	//这只是一个示例代码,其他功能不做展示
private:
	Stack _st1;
	Stack _st2;
	int _size = 0;	//C++11规定,内置类型在声明时可以用缺省值初始化
};

int main()
{
	MyQueue mq;

	return 0;
}

我们运行,可以看到:

在这里插入图片描述

尽管我们没给类MyQueue写构造函数,编译器采用的是自动生成的默认构造,但是里面的两个成员变量st1和st2都已经被初始化。这是因为这个默认构造碰到自定义类型Stack时,就会调用Stack类的构造函数

因此我们可以得出结论:

对于编译器自动生成的构造函数,

  • 对内置类型(int、char、指针等)不做处理
  • 对自定义类型,调用它自己的构造函数

同时,C++也规定,除了我们自己不写,系统自动生成的构造函数叫做默认构造,没有参数的构造函数、参数全为缺省的构造函数也都可以被看作是默认构造,同时,默认构造有且只有一个

1.3 构造函数的调用

构造函数不需要人为调用,由编译器自动调用,且在一个对象的生命周期内,构造函数只会调用一次

Date类为例:

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

private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2023, 11, 1);	//方法一
	Date d2(2024);	//方法二:注意缺省参数的使用
	Date d3;	//方法三:特别注意,如果不传参,那么就不要带括号
}

这里特别注意第三种实例化对象的方式,如果不传参,那么一定不能带括号**,否则编译器就不能区分这到底是一个函数的声明还是一个对象的实例化**:

int main()
{
	Date d3();
	d3._year = 2022;

	return 0;
}
//报错:“._year”的左边必须有类/结构/联合
//说明编译器认为d3不是类

2. 析构函数

在这里插入图片描述

和构造函数相反,析构函数就是用来完成对象中资源清理的成员函数

2.1 析构函数的声明和定义

规定:

  • 析构函数的函数名为~ classname
  • 析构函数没有返回值
  • 析构函数没有形参
  • 析构函数不支持函数重载

例如对于Stack类,它的析构函数就是:

~Stack()
{
    free(_a);	//清理资源——释放动态开辟的空间
    _a = nullptr;
    _capacity = _top = 0;
}

2.2 默认析构函数

和默认构造函数一样,如果自己不写析构函数,那么编译器就会自动生成一个析构函数

同时,这个默认析构对于成员变量的处理方式和默认构造一样:

  • 对内置类型不做处理
  • 对自定义类型,调用他自己的析构函数

例如,对于Stack类,如果我们不写析构函数:

在这里插入图片描述

可以看到,对象st1的生命周期结束了其里面的成员变量_a都没有销毁,而_a的空间是动态开辟出来的,这就导致了内存泄漏,这是非常危险的

而对于MyQueue类,如果不写析构函数:

在这里插入图片描述

可以看到,两个Stack对象里的空间都已经被释放,这就是因为对于自定义类型,默认析构会调用它的析构函数

2.3 析构函数的调用及其必要性

当对象的生命周期结束时,编译器会自动调用析构函数,无需人为调用

什么情况必须写析构函数:

如果该对象在构造时用指针动态开辟了空间(申请了资源),那么就必须自己声明和定义析构函数来清理这部分资源,否则就会造成内存泄漏

什么情况可以不写:

  • 类的成员都是自定义类型
  • 类的成员在构造时没有申请空间资源(如Date类)

下一章,我们将继续讲C++类里面的默认成员函数——拷贝构造和赋值重载,以及运算符重载等相关知识。
如果觉得本篇对你有所帮助或者对以后的内容感兴趣,不妨关注专栏👉C++教程
请添加图片描述

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

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

相关文章

Unity Animator cpu性能测试

测试案例: 场景中共有4000个物体,挂在40个animtor 上,每个Animator控制100个物体的动画。 使用工具: Unity Profiler. Unity 版本: unity 2019.4.40f1 测试环境: 手机 测试过程: 没有挂…

解读电力系统中的GPS北斗卫星同步时钟系统

随着电力系统的快速发展,变电站中的各类系统 :计算机监控系统、水情测报系统、视频监控系统 状态监测系统 生产信息管理系统等,各类装置:继电保护装置、故障录波装置、PMU装置、事件顺序记录SOE功能越来越强大,需要采集、记录的数…

CSS3背景样式

在CSS 2.1中,background属性的功能还无法满足设计的需求,为了方便设计师更灵活地设计需要的网页效果,CSS3在原有background基础上新增了一些功能属性,可以在同一个对象内叠加多个背景图像,可以改变背景图像的大小尺寸&…

LeetCode热题100 48.旋转图像

题目描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1: 输入:matrix [[1,2,3],[4,5,6],[7,8,9…

2022年09月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 运行以下代码,结果输出的是?( ) means[Thank,You] print(len(means))A…

Android开发知识学习——TCP / IP 协议族

文章目录 学习资源来自:扔物线TCP / IP 协议族TCP连接TCP 连接的建立与关闭TCP 连接的建立为什么要三次握手? TCP 连接的关闭为什么要四次挥手? 为什么要⻓连接? 常见面试题课后题 学习资源来自:扔物线 TCP / IP 协议…

潜力无限!深眸科技以工业视觉软硬件一体化解决方案深入应用场景

工业视觉作为智能制造的眼睛,在制造业各场景中具有广泛的应用前景,尤其是在检测、引导、定位、测量等方面应用需求不断提高。深眸科技为进一步巩固和加强技术领先优势,持续拓宽机器视觉技术的应用边界,通过先进的硬件设备和自研的…

86 最小栈

最小栈 题解1 STL大法好题解2 辅助最小栈(直观,空间换时间)题解3 不需要额外空间(!!!差值!!!) 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初…

支持「导入/导出」,应用迁移瞬间完成_三叠云

应用导入/导出 路径 应用管理 >> 创建新应用 功能简介 1. 应用程序支持「导出」功能,即将应用独立封装导出,用于三叠云系统内应用导入。 2. 应用程序支持「导入」功能,可以帮助用户将数据或文件导出到其他设备或应用程序中&#x…

思维导图在学习中的应用

思维导图在做学习中发挥着非常高效的作用,因为因为思维导图只有一页,所以需要准备和组织内容的时间会大大减少。并且思维导图的可视化的结构,可以让你瞬间将所有信息一览无余。而传统的笔记方法,会记录好几页。不仅信息冗杂&#…

【经典面试】87 字符串解码

字符串解码 题解1 递归(程序栈)——形式语言自动机(LL(1)) : O(S)另一种递归(直观) 题解2 2个栈(逆波兰式)1个栈(参考官方,但是不喜欢) 给定一个经过编码的字符串,返回它解码后的字符串。 编码规则为: k[encoded_string],表示其中方括号内部的…

Linux 权限管理(二)

文件类型和访问权限(事物属性) linux前都会有一串这个字符,第二字符到第九字符分别表示拥有者,所属组,和other所对应的权限。那么第一个字符表示什么呢? 第一个字符表示文件类型: d&#xff1a…

开放式耳机百元价位推荐哪款比较好一点、最值得入手的开放式耳机

不知道有没有和我一样的朋友,在工作的时候喜欢带着耳机,享受音乐带来的愉悦。然而,传统的入耳式耳机在长时间佩戴时会给耳朵带来不适感,甚至损害听力。 因此我现在会使用开放式耳机,采用了开放式设计,不需…

流程封装与基于加密接口的测试用例设计

接口测试仅仅掌握 Requests 或者其他一些功能强大的库的用法,是远远不够的,还需要具备能根据公司的业务流程以及需求去定制化一个接口自动化测试框架的能力。所以,接下来,我们主要介绍下接口测试用例分析以及通用的流程封装是如何…

算法通关村第四关-青铜挑战基于链表完成栈

大家好我是苏麟 , 今天聊聊. 本期大纲 栈的基础知识栈的特征栈的操作Java中的栈 基于链表实现栈 栈的基础知识 栈的特征 栈和队列是比较特殊的线性表,又称之为访问受限的线性表。栈是很多表达式、符号等运算的基础,也是递归的底层实现。理论上递归能做…

进阶课5——人工智能数据分类

数据类型是指数据在计算机中的存储方式,根据数据的不同特征和表示方式,可以将数据分为不同的类型。在IT领域中,随着数字化信息技术的应用不断扩大,数据的种类和格式也越来越多。 从人机交互数据类型的视角来看,人工智…

RSA加密解密

生成公钥私钥: /*** RSA 生成公钥私钥*/ public class CreateSecrteKey {public static final String KEY_ALGORITHM "RSA";private static final String PUBLIC_KEY "RSAPublicKey";private static final String PRIVATE_KEY "RSAPri…

pytorch复现1_VGG

不涉及太多原理 VGG在2014年由牛津大学著名研究组VGG (Visual Geometry Group) 提出,斩获该年ImageNet竞赛中 Localization Task (定位任务) 第一名 和 Classification Task (分类任务) 第二名。 网络亮点: 1.通过堆叠多个3x3的卷积核来替代大尺度卷积核…

腾讯云轻量应用服务器“镜像”怎么选择合适?

腾讯云轻量应用服务器镜像怎么选择?如果是用来搭建网站可以选择宝塔Linux面板腾讯云专享版,镜像系统根据实际使用来选择,腾讯云百科txybk.com来详细说下腾讯云轻量应用服务器镜像的选择方法: 腾讯云轻量应用服务器镜像选择 轻量…