C++的六大“天选之子“之“构造“与“析构“

news2024/10/9 14:18:25

在这里插入图片描述

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨
🐻推荐专栏1: 🍔🍟🌯C语言初阶
🐻推荐专栏2: 🍔🍟🌯C语言进阶
🔑个人信条: 🌵知行合一
🍉本篇简介:>:讲解C++中有关类和对象的介绍,本篇是中篇的第一篇文章.
金句分享:
✨别在最好的年纪,辜负了最好的自己.✨

目录

  • 一、"构造函数"与"析构函数"
    • 1.1 "构造函数"
      • (1) 自动生成的"构造函数"
      • (2) 自定义"构造函数"
      • 总结:
    • 1.2 "析构函数"
      • 总结:

一、“构造函数"与"析构函数”

1.1 “构造函数”

不知道友友们有没有过这样一段经历.
在写一道数据结构的oj题时,信心满满的提交后,发现,编译居然编译不过,找了半天发现是忘记了进行初始化操作.
很多时候我们经常忘记初始化操作,但是初始化操作每次又是必做的,那么C++的祖师爷(本贾尼大佬)就贴心的给我设计了一个函数,这个函数就是构造函数.

构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。

在这里插入图片描述

(1) 自动生成的"构造函数"

构造函数编译器会自动调用,那我们不写构造函数会怎样呢?

下面这段代码会报错吗?

#include <iostream>
using std::cin;
using std::cout;
using std::endl;
class Date
{
public:
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1;
	d1.Print();
	Date d2;
	d2.Print();
	return 0;
}

在这里插入图片描述
答案:

并不会报错,因为构造函数即使如果在类中没有显式定义,编译器也会自动生成一个默认的析构函数

运行结果:

-858993460–858993460–858993460
-858993460–858993460–858993460

但是.构造函数对于内置类型(例如:int ,double,指针等等)并不做处理,对于自定义类型(结构体,类,联合,枚举等等),会调用自定义类型自己的构造函数.

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

class Time
{
public:
	Time()//Time类的默认构造函数
	{
		cout << "Time的构造函数" << endl;
		_hour = 0;
		_minute = 0;
		_second = 0;
	}
	void Print()
	{
		cout << _hour << "-" << _minute << "-" << _second << endl;
	}
private:
	int _hour;
	int _minute;
	int _second;
};

class Date
{
public:
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
		_time.Print();//打印时间
	}
private:
	int _year;
	int _month;
	int _day;
	Time _time;
};

int main()
{
	Date d1;
	d1.Print();
	Date d2;
	d2.Print();
	return 0;
}

运行结果:

Time的构造函数
-858993460–858993460–858993460
0-0-0

Time的构造函数
-858993460–858993460–858993460
0-0-0

解释:
虽然Date类我们没有写构造函数,但是编译器自动生成了一个隐藏的构造函数并且对自定义类型(这里是Time类)会调用自己的构造函数,所以Time类中的成员已经初始化了.

(2) 自定义"构造函数"

前面提到,内置类型,默认构造函数是不进行处理的,而这显然是设计的不合理的,所以在C++11中,打了个补丁,内置类型成员变量在类中声明时可以给默认值(缺省值),记住这里是默认值,并不是真的存储变量,因为声明是没有空间存储变量的.类只是图纸,并不能住人,只有实例化成对象后,才可以住人.

示例:下面这段代码并没有显示定义构造函数.

#include <iostream>
using std::cin;
using std::cout;
using std::endl;
class Date
{
public:
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year=2020;//类中只是声明,并不存储变量,这里给出的是缺省值(很重要)
	int _month=10;
	int _day=1;
};

int main()
{
	Date d1;
	d1.Print();
	printf("\n");
	Date d2;
	d2.Print();
	return 0;
}

运行结果:

2020-10-1

2020-10-1

常见的三种默认构造函数:

  1. 无参构造函数
  2. 全缺省构造函数
  3. 带参构造函数

当然,学过函数重载的友友 们一定知道全缺省和无参会存在调用不明确的情况.

class Date
{
public:
	Date()//无参构造函数
	{
		_year = 2020;
		_month = 1;
		_day = 1;
	}
	Date(int year=2020,int month=1,int day=1)//全缺省构造函数
	{
		_year = year;
		_month = month;
		_day = day;
	}
	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;
};

运行结果:

总结:

  1. 构造函数的函数名与类名相同。无返回值(不是void)。
  2. 对象实例化时编译器自动调用对应的构造函数。
  3. 构造函数可以重载。(为了解决满足多样的初始化要求)
  4. 默认构造函数是对内置类型不进行处理,C++11中,打了个补丁,内置类型成员变量在类中声明时可以给默认值(缺省值)
  5. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成,所以无参,全缺省,默认构造函数只能有一个.

1.2 “析构函数”

同样,我们设计构造函数的目的是帮助我们自动调用初始化操作,因为初始化操作经常忘记且又是必须的.那析构函数呢?
析构函数是很多时候我们经常忘记销毁操作,如果是动态申请的空间,很容易导致内存泄漏,那么我们亲爱的C++的祖师爷(本贾尼大佬)就又给我们设计了一个函数,这个函数就是析构函数.

析构函数:

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

构造函数名与类名相同,那析构函数呢?
析构函数名是在类名前加上字符 ~。

示例:

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

typedef int DataType;
class Stack
{
public:
	Stack(int capacity=5)//全缺省构造函数
	{
		cout << "Stack" << endl;
		_array = (DataType*)malloc(sizeof(DataType) * capacity);
		if (NULL == _array)
		{
			perror("malloc申请空间失败!!!");
			return;
		}
		_capacity = capacity;
		_size = 0;
	}
	void Push(DataType data)//压栈操作
	{
		CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	~Stack()//析构函数
	{
		cout << "~Stack"<< endl;
		if (_array)
		{
			free(_array);
			_array = NULL;
			_capacity = 0;
			_size = 0;
		}
	}
private:
	void CheckCapacity()
	{
		if (_size == _capacity)
		{
			int newcapacity = _capacity * 2;
			DataType* temp = (DataType*)realloc(_array, newcapacity *
				sizeof(DataType));
			if (temp == NULL)
			{
				perror("realloc申请空间失败!!!");
				return;
			}
			_array = temp;
			_capacity = newcapacity;
		}
	}
private:
	DataType* _array;
	int _capacity;
	int _size;
};
int main()
{
	Stack s;
	s.Push(1);
	s.Push(2);
	s.Push(3);
	s.Push(4);
	return 0;
}

运行结果:

Stack
~Stack

我们不难发现,即使我们不写函数调用,构造函数析构函数都会被自动调用.不愧是祖师爷的亲儿子,两个函数都有特权.

总结:

  1. 析构函数名是类名前加上字符 ~。无参数无返回值类型。
  2. 构造函数不同的是,析构函数不支持函数重载,所以一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数
  3. 对象生命周期结束时,C++编译系统系统自动调用析构函数。
  4. 编译器生成的默认析构函数自定义类型会调用它自己的析构函数,析构函数对于内置类型,不会有任何影响,因为内置类型的对象没有需要释放的资源。
  5. 如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如Date类;有资源申请时,一定要写,否则会造成资源泄漏,比如Stack类。但是呢,牛牛建议还是都写吧,否则忘记写就可能发生内存泄漏,反正不难.

本篇文章只提到了"构造"与"析构"函数这两个天选之子,还有四个没有登场哦!敬请期待吧!

在这里插入图片描述

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

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

相关文章

【LeetCode】64.最小路径和

题目 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只能向下或者向右移动一步。 示例 1&#xff1a; 输入&#xff1a;grid [[1,3,1],[1,5,1],[4,2,1]] 输出&#…

离多态更近一步

在面向对象的语言里面,封装,继承,多态可谓是在熟悉不过了,当我们每次再去重新认识它们的时候总会有新的发现,为此我也经常感到疑惑,所以在这里和大家一起探讨三个问题,让我们在向多态靠近一点点。 虚表是否真的存在静态区 经常我们都会看见一个问题&#xff0c;虚表到底是存放…

使用show effective grants查看权限

1、问题描述 用户 show grants 显示只有连接权限&#xff0c;但该用户却能执行 sbtest.*下的所有操作 GreatSQL> \s ... Server version: 8.0.32-24 GreatSQL, Release 24, Revision 3714067bc8c ... GreatSQL> show grants; ---------------------------------------…

哪些在线工具能免费转换MP3格式?分享两个方法!

哪些在线工具能免费转换MP3格式&#xff1f;通常来说&#xff0c;MP3格式转换器都具备简洁的界面、便捷的操作以及强大的功能&#xff0c;它们可以将各种流行的视频或音频格式转换成MP3文件&#xff0c;甚至可以制作手机铃声。用户只需要在设置中设定录制时间&#xff0c;即可轻…

MIT 6.830数据库系统 -- lab four

MIT 6.830数据库系统 -- lab four 项目拉取引言事务、锁 & 并发控制事务ACID特性两阶段锁 Recovery and Buffer ManagementGranting Locks(授予锁)练习1 Lock Lifetime练习2 Implementing NO STEAL练习3 事务练习4 死锁和中止练习5 项目拉取 原项目使用ant进行项目构建&am…

勘探开发人工智能应用:初至波拾取

AI在油田主营业务即勘探开发运销和经营管理领域的落地场景&#xff0c;需要的算法、模型及关键技术。 1 初至波拾取 在地震数据采集过程中&#xff0c;由人工震源激发后检波器最先接收到地震波的起跳位置&#xff0c;得到这一位置的过程就是初至拾取。“初至拾取在构建精细近…

AI生成写真照 妙鸭能取代海马体?

只要9.9元和21张照片&#xff0c;就能生成各种风格的个人写真照&#xff0c;界面简洁、卖点吸睛的妙鸭相机突然火了。采用AI技术&#xff0c;它以更低的成本和更高的效率&#xff0c;让用户足不出户“拍写真”&#xff0c;有人直呼&#xff0c;它要抢海马体这类实体照相馆的饭碗…

基于51单片机和proteus的模拟楼道灯系统

此系统是基于51单片机和proteus的仿真设计&#xff0c;功能如下&#xff1a; 1. 系统实时检测楼道光照强度。 2. 光照弱情况下&#xff0c;触摸或声音可开启楼道灯。 3. 光照强情况下&#xff0c;触摸或声音都不能开启楼道灯。 4. 楼道灯开启一段时间&#xff08;3S&#x…

数据库应用:MySQL MHA高可用集群

目录 一、理论 1.MHA 2.MySQL MHA部署准备 3.MySQL MHA部署 二、实验 1.MHA部署 三、问题 1.中英文符兼容报错 2.MHA测试 ssh 无密码认证语法报错 3.MHA测试 ssh 无密码认证log-bin报错 4.MHA测试 mysql 主从连接情况报错slave replication 5.MHA测试 mysql 主从连…

高质量代码究竟依赖设计还是重构而来?

&#x1f449;导读 一个有所追求的程序员一定都希望自己能够写出高质量的代码&#xff0c;但高质量代码从何而来呢&#xff1f;有人认为是设计出来的&#xff0c;就像一栋稳固的大厦&#xff0c;如果没有前期优秀的设计那么肯定难逃豆腐渣工程的命运&#xff1b;也有人认为是重…

什么是NQA?

一、什么是NQA&#xff1f; 网络质量分析NQA&#xff08;Network Quality Analysis&#xff09;是一种实时的网络性能探测和统计技术&#xff0c;可以对响应时间、网络抖动、丢包率等网络指标进行统计。NQA能够实时监视网络服务质量&#xff0c;在网络发生故障时进行有效的故障…

年内实现全面自动驾驶?快来恶补一下自动驾驶技术吧

在7月6日召开的2023世界人工智能大会上&#xff0c;特斯拉CEO斯克预测&#xff0c;随着人工智能技术的快速发展&#xff0c;大约在今年年末&#xff0c;就会实现全面自动驾驶。 他说&#xff0c;“我之前也做过许多类似的预测&#xff0c;我承认之前的预测也不完全准确&#x…

《中国大学生计算机设计大赛》应用与开发组 “国二省一“ 备赛心得,万字干货 (建议收藏)

&#x1f4a7; 《中国大学生计算机设计大赛》备赛心得 \color{#FF1493}{《中国大学生计算机设计大赛》备赛心得} 《中国大学生计算机设计大赛》备赛心得&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞见云的博客…

Python编译过程和执行原理

hello&#xff0c;这里是Token_w的文章&#xff0c;主要讲解python的基础学习&#xff0c;希望对大家有所帮助 整理不易&#xff0c;感觉还不错的可以点赞收藏评论支持&#xff0c;感谢&#xff01; 目录 一. Python执行原理二. Python内部执行过程2.1 编译过程概述2.2 过程图解…

8.6 PowerBI系列之DAX函数专题-非日期类型的累计聚合

需求 需求1&#xff1a; 需求2&#xff1a; 实现 1.需求1实现&#xff1a; &#xff08;1&#xff09;在power query中添加列-添加索引列&#xff1b; &#xff08;2&#xff09;根据索引列进行累加计算。 度量值 累计聚合销售额 var current_pro_type selectedvalue(…

iTOP-RK3588开发板编译Buildroot

Buildroot 是一款集成的编译集合包&#xff0c;解决了以前交叉编译麻烦的问题&#xff0c;本小节将介绍 buildroot 镜像的编译流程&#xff0c;分为单独编译和完整全自动编译。 首先输入以下命令&#xff0c;选择 buildroot 系统的配置文件 source buildroot/build/envsetup…

办公楼管理高手:一起来学烟雾监测实用技能!

在现代社会中&#xff0c;安全意识和防患意识越来越受到重视。特别是在大型办公楼等人员密集的场所&#xff0c;火灾的风险不容忽视。 为了保障员工和资产的安全&#xff0c;烟感监控成为一项至关重要的安全措施。烟感监控系统作为火灾预警的关键组成部分&#xff0c;能够及早发…

Ubuntu18.04未安装Qt报qt.qpa.plugin could not load the Qt platform plugin xcb问题的解决方法

在Ubuntu 18.04开发机上安装了Qt 5.14.2&#xff0c;当将其可执行程序拷贝到另一台未安装Qt的Ubuntu 18.04上报错&#xff1a;拷贝可执行程序前&#xff0c;使用ldd将此执行程序依赖的动态库也一起拷贝过去&#xff0c;包括Qt5.14.2/5.14.2/gcc_64/plugins目录系的platforms目录…

实现基于UDP简易的英汉词典

文章目录 实现目标认识相关接口socketbzerobindrecvfromsendto 实现思路和注意事项完整代码Server.hppServer.ccClient.hppClient.cc 运行效果END 实现目标 实现一个服务端和一个客户端&#xff0c;客户端负责发送一个单词&#xff0c;服务端接收到后将翻译后的结果返回发送到…

学术研究 #可视化工具 #学术文献绘图 #研究利器 #Citespace #vosviewer

目录 专题一 文献计量学方法与应用简介 专题二 主题确定、检索与数据采集 专题三 VOSviewer可视化绘图精讲 专题四 Citespace可视化绘图精讲 专题五 R语言文献计量学绘图分析 专题六 论文写作 专题七 论文投稿 文献计量学是指用数学和统计学的方法&#xff0c;定量地分析…