构造函数和析构函数

目录

一:类的六个默认函数

二:构造函数 

2.1概念

2.2特性

 三:析构函数

3.1概念:

3.2特性


一:类的六个默认函数

如果一个类中什都没有,称为空类

空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成一下六个默认成员函数。

默认成员函数:用户没有显示实现,编译器会生成的成员函数成为默认成员函数


二:构造函数 

2.1概念

对于下面Date类:

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(2424, 10, 2);
	d1.Print();

	Date d2;
	d2.Init(2024, 4, 6);
	d2.Print();

	return 0;
}
对于 Date 类,可以通过 Init 公有方法给对象设置日期,但如果每次创建对象时都调用该方法设置
信息,未免有点麻烦,那能否在对象创建时,就将信息设置进去呢?
构造函数 是一个 特殊的成员函数,名字与类名相同 , 创建类类型对象时由编译器自动调用 ,以保证
每个数据成员都有 一个合适的初始值,并且 在对象整个生命周期内只调用一次

2.2特性

构造函数是一种特殊的成员函数,需要注意的是,构造函数虽然名字是构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象(类似 Init的功能)

其特征如下:
1.函数名与类名相同

2.无返回值(也不需要写void)

3.对象实例化时编译器自动调用对应的构造函数

4.构造函数可以重载

class Date
{
public:
	//1.无参构造函数
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}

	//2.有参函数
	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 d1()与函数的声明无法分开,不可以这样写
	Date d1;//调用无参构造函数
	d1.Print();

	//Date d2(int x, int y, int z)与函数声明可以分开
	Date d2(2024,10,5);//构造有参构造函数
	d2.Print();

	return 0;
}

一般构造函数,都写成全缺省函数,这样可以把前面两种情况都包含在内了

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;
	d1.Print();

	Date d2(2024,10,5);
	d2.Print();

	Date d3(2424);
	d3.Print();
	return 0;
}

5.如果类中没有显示定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显示定义编译器将不再生成

6.关于编译器生成的默认成员函数,很多童鞋会有疑惑:不实现构造函数的情况下,编译器会生成默认的构造函数。但是看起来默认构造函数又没什么用?d对象调用了编译器生成的默认构造函数,但是d对象_year/_month/_day,依旧是随机值。

也就说在这里编译器生成的默认构造函数并没有什么用??

解答:C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语言提供的数据类型,如:int/char/double/任何类型的指针...,自定义类型就是我们使用class/struct/union等自己定义的类型

编译器自动生成的构造函数,对于内置成员变量,没有具体规定处不处理,具体情况看编译器

对于自定义类型的成员变量才会调用它的无参构造

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;
	int _month;
	int _day;

	//自定义类型
	Time _t;
};

int main()
{
	Date d1;
	
	return 0;
}

如果自定义类型中没有无参函数的话,会报错

Time(int hour)
	{
		cout << "Time()" << endl;
		_hour = 0;
		_minute = 0;
		_second = 0;
	}

 如果,没有在Time中没有定义显示构造函数,就会用编译器默认生成的,又由于Time中的成员变量有都是内置类型,所以又会赋值随机值

编译器自动构造函数的意义?

如果一个类中均是自定义类型,在初始化时不用再重新定义构造函数,就可以直接初始化

class Stack
{
public:

	Stack()
	{
		_a = (int*)malloc(sizeof(int) * 4);

		if (_a == nullptr)
		{
			perror("malloc fail");
			return;
		}
		_top = 0;
		_capacity = 4;
	}

	void Push(int x)
	{
		if (_capacity == _top)
		{
			int newCapacity = 2 * _capacity;
			int* tmp = (int*)realloc(_a,sizeof(int) * newCapacity);

			if(tmp == nullptr)
			{
				perror("tmp realloc fail");
				return;
			}

			_a = tmp;
			_capacity = newCapacity;
		}

		_a[_top++] = x;
	}

	void Pop()
	{
		_top--;
	}

	int Top()
	{
		return _a[_top - 1];
	}

	bool Empty()
	{
		return _top == 0;
	}

	void Destroy()
	{
		free(_a);
		_a = nullptr;
		_top = _capacity = 0;
	}

private:
	int* _a;
	int _top;
	int _capacity;
};

class MyQueue
{

	Stack _popst;
	Stack _pushst;
};

int main()
{
	MyQueue q;

	return 0;
}


 三:析构函数

3.1概念:

通过前面构造函数的学习,我们知道一个对象是怎么来的,那一个对象又是怎么没呢的?
析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由
编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理(malloc, fopen,链接数据库....)工作

3.2特性

析构函数是特殊的成员函数,其特征如下:
1. 析构函数名是在类名前加上字符 ~。
2. 无参数无返回值类型。
3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构
函数不能重载
4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。
~Stack()
{
	free(_a);
	_a = nullptr;
	_top = _capacity = 0;

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL客户端安装并配置免密登录

最近在写脚本时需要向MySQL数据库中存储数据&#xff0c;且脚本运行的服务器与MySQL服务器不是同一台服务器&#xff0c;而且需要保证MySQL密码的安全性&#xff0c;不能在脚本中暴露&#xff0c;所以就需要在服务器上安装MySQL客户端&#xff0c;并配置免密登录。 一、虚拟机…

C++ List 到 Python List 的转换

当我们编写 C 库的封装器通常涉及使用一种跨语言的接口技术&#xff0c;比如使用C接口或者使用特定的跨语言库&#xff0c;比如SWIG&#xff08;Simplified Wrapper and Interface Generator&#xff09;或者Pybind11。这里我将简要介绍如何使用Pybind11来封装一个C库&#xff…

jenkins+docker实现可持续自动化部署springboot项目

目录 一、前言 二、微服务带来的挑战 2.1 微服务有哪些问题 2.2 微服务给运维带来的挑战 三、可持续集成与交付概述 3.1 可持续集成与交付概念 3.1.1 持续集成 3.1.2 持续交付 3.1.3 可持续集成与交付核心理念 3.2 可持续集成优点 3.3 微服务为什么需要可持续集成 四…

金三银四面试题(十五):Java基础问题(6)

这部分面试题多用于面试的热身运动&#xff0c;对很多找实习和准备毕业找工作的小伙伴至关重要。 HashMap与ConcurrentHashMap 都是key-value 形式的存储数据&#xff1b; HashMap 是线程不安全的&#xff0c;ConcurrentHashMap 是JUC 下的线程安全的&#xff1b; HashMap 底层…

降低笔记本电脑噪音的七种方法,看下有没有适合你的

序言 无论是玩游戏、浏览网络还是做严肃的工作,差不多都有这么一台笔记本电脑,它有足够的处理能力来处理几乎任何事情。不幸的是,它可能会变得非常大声,但有办法来遏制这种噪音。 清洁通风口和风扇,并使用硬表面 如果你的笔记本电脑现在比过去运行同样的软件时声音更大…

docker笔记(二):镜像、容器数据卷

四、 docker镜像 4.1 镜像 镜像是一种轻量级、可执行的独立软件包&#xff0c;用来打包软件运行环境和基于运行环境开发的软件&#xff0c;它包含运行某个软件所需的所有内容&#xff0c;包括代码、库、环境变量和配置文件 所有的应用&#xff0c;直接打包docker镜像就可以直…

深度学习500问——Chapter05: 卷积神经网络(CNN)(4)

文章目录 5.18 卷积神经网络凸显共性的方法 5.18.1 局部连接 5.18.2 权值共享 5.18.3 池化操作 5.19 全连接、局部连接、全卷积与局部卷积 5.20 局部卷积的应用 5.21 NetVLAD池化 参考文献 5.18 卷积神经网络凸显共性的方法 5.18.1 局部连接 我们首先了解一个概念&#xff0c…

Office办公软件之Excel的使用(一)

1、“开始”菜单中的部分属性 2、制作斜线表头 ctrl1,弹出设置单元格格式&#xff0c;选择“边框”&#xff0c;点击右下角有斜线的即可。 3、冻结窗口 一般冻结首列或首行&#xff0c;当我们翻页的时候&#xff0c;也能看到每一行的描述。 4、快捷键 1、 Ctrl1 设置单元格格…

【Java基础知识总结 | 第十篇】HashSet底层实现原理

文章目录 10.HashSet底层实现原理10.1HashSet特点10.2HashSet源码10.3 add流程10.4总结 10.HashSet底层实现原理 10.1HashSet特点 存储对象&#xff1a;HashSet 存储对象采用哈希表的方式&#xff0c;它不允许重复元素&#xff0c;即集合中不会包含相同的元素。当向 HashSet …

C语言实现快速排序算法

1. 什么是快速排序算法 快速排序的核心思想是通过分治法&#xff08;Divide and Conquer&#xff09;来实现排序。 算法的基本步骤是: 1. 选择一个基准值&#xff08;通常是数组中的某个元素&#xff09;&#xff0c;将数组分成两部分&#xff0c;使得左边的部分所有元素都小于…

2024.4.1-[作业记录]-day06-认识 CSS(三大特性、引入方式)

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; day06-认识 CSS(三大特性、引入方式) 文章目录 day06-认识 CSS(三大特性、引入方式)作业…

xss.pwnfunction-Ma Spaghet!

根据代码得知 这个是根据get传参的并且是由someboby来接收参数的 所以 <script>alert(1137)</script> js并没有执行因为 HTML5中指定不执行由innerHTML插入的<script>标签 所以 ?somebody<img%20src1%20onerror"alert(1337)"> 这样就成…

Java栈和队列的实现

目录 一.栈(Stack) 1.1栈的概念 1.2栈的实现及模拟 二.队列(Queue) 2.1队列的概念 2.2队列的实现及模拟 2.3循环队列 2.4双端队列&#xff08;Deque&#xff09; 一.栈(Stack) 1.1栈的概念 栈:一种特殊的线性表&#xff0c;其 只允许在固定的一端进行插入和删除元素操作…

JavaWeb--JavaScript Part 01

1. JavaScript概述 JavaScript&#xff08;简称JS&#xff09;是一种轻量级的、解释执行的客户端脚本语言&#xff0c;主要用于增强网页的交互性和动态性。它起源于Netscape的LiveScript&#xff0c;并在1995年发布时更名为JavaScript。尽管名称中包含"Java"&#xf…

JS 利用 webcam访问摄像头 上传到服务器

webcam JS 较为详细的指南 定义标题 <!doctype html> <html> <head><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>How to capture picture from webcam with Webcam.js</title></…

FreeMarker系列--指令的用法(全面,有示例)

原文网址&#xff1a;FreeMarker系列--指令的用法(全面&#xff0c;有示例)_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍FreeMark指令的用法。 相关网址 中文官方参考手册 assign 描述 使用该指令你可以创建一个新的变量&#xff0c; 或者替换一个已经存在的变量。注…

Redis实现高可用持久化与性能管理

前言 在生产环境中&#xff0c;为了实现Redis的高可用性&#xff0c;可以采用持久化、主从复制、哨兵模式和 Cluster集群的方法确保数据的持久性和可靠性。这里首先介绍一下使用持久化实现服务器的高可用。 目录 一、Redis 高可用方法 1. 持久化 2. 主从复制 3. 哨兵 4.…

2024.4.5-[作业记录]-day10-CSS 布局模型(层模型)

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 作业 2024.4.5-学习笔记1 CSS定位1.1 相对定位 relative1.2 绝对定位 absolut…

【C++】map set 底层刨析

文章目录 1. 红黑树的迭代器2. 改造红黑树3. map 的模拟实现4. set 的模拟实现 在 C STL 库中&#xff0c;map 与 set 的底层为红黑树&#xff0c;那么在不写冗余代码的情况下使用红黑树同时实现 map 与 set 便是本文的重点。 1. 红黑树的迭代器 迭代器的好处是可以方便遍历&…

Day84:服务攻防-端口协议桌面应用QQWPS等RCEhydra口令猜解未授权检测

目录 端口协议-口令爆破&未授权 弱口令爆破 FTP&#xff1a;文件传输协议 RDP&#xff1a;Windows远程桌面协议 SSH&#xff1a;Linux安全外壳协议 未授权案例(rsync) 桌面应用-QQ&WPS&Clash QQ RCE 漏洞复现 WPS RCE 漏洞复现 Clas* RCE 漏洞复现 知识点…