C++——类和对象(2)

1. 类的6个默认成员函数

当一个类中什么都没有,编译器会帮类自动生成6个默认成员函数例如:

class Date
{

};

此篇文章主要围绕构造函数与析构函数进行讲解。


2. 构造函数

2.1 概念

#define  _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;


class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	void Init(int year = 1,int month = 1 ,int day = 1)
	{
		this->_year = year;
		this->_month = month;
		this->_day = day;
		cout << "今天是" << _year << "/" << _month << "/" << _day << endl;
	}
};

int main()
{
	Date d1;
	d1.Init(2024, 3, 15);
	return 0;
}
  •  对于以上的Date类,每次实例化对象之后都要对对象调用Init()函数,比较繁琐,其实编译器就可以帮我们完成。
  • 构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。

2.2 特性

构造函数是特殊的成员函数,其定义语法上有以下几点:

  1. 构造函数函数名与类名相同;
  2. 无返回值;
  3. 构成重载;
  4. 对象实例化时编译器自动调用构造函数。
class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	//带参构造函数
	Date(int year, int month = 1, int day = 1)
	{
		this->_year = year;
		this->_month = month;
		this->_day = day;
		cout << "今天是" << _year << "/" << _month << "/" << _day << endl;
	}
	//无参构造函数
	Date()
	{
		this->_year = 1;
		this->_month = 1;
		this->_day = 1;
		cout << "今天是" << _year << "/" << _month << "/" << _day << endl;
	}
};

int main()
{
	Date d1;
	Date d2(2024, 3, 15);
	return 0;
}
  • 如果你在类中没有给出构造函数,那么编译器将会自动给出构造函数,如果给了构造函数,编译器就不会生成:
class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	带参构造函数
	//Date(int year, int month = 1, int day = 1)
	//{
	//	this->_year = year;
	//	this->_month = month;
	//	this->_day = day;
	//	cout << "今天是" << _year << "/" << _month << "/" << _day << endl;
	//}
	无参构造函数
	//Date()
	//{
	//	this->_year = 1;
	//	this->_month = 1;
	//	this->_day = 1;
	//}
	void Print()
	{
		cout << "今天是" << _year << "/" << _month << "/" << _day << endl;

	}
};

int main()
{
	Date d1;
	d1.Print();
	//Date d2(2024, 3, 15);
	return 0;
}

  •  以下这种情况就是你写了一份构造函数,但是没有匹配的,编译器也不会帮你生成。
class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	//带参构造函数
	Date(int year, int month = 1, int day = 1)
	{
		this->_year = year;
		this->_month = month;
		this->_day = day;
		cout << "今天是" << _year << "/" << _month << "/" << _day << endl;
	}
	//无参构造函数
	/*Date()
	{
		this->_year = 1;
		this->_month = 1;
		this->_day = 1;
	}*/
	/*void Print()
	{
		cout << "今天是" << _year << "/" << _month << "/" << _day << endl;

	}*/
};

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

  • 如果你没有构造函数,编译器会帮你调用构造函数,在它本身的构造函数中,如果是内置类型,例如(int ,double, char,指针类型等),则编译器不会帮你初始化,如果不是内置类型,例如(struct,class定义自定义类型等),编译器会帮你调用它的构造函数,例如以下是两个栈实现队列的简单定义:
struct Stack
{
	int* _a;
	int _top;
	int _capacity;
    // 栈的构造函数
	Stack()
	{
		_a = nullptr;
		_capacity = 0;
		_top = 0;
		cout << "This is Stack struct" << endl;
	}
	void CheckCapacity()
	{
		if (_top == _capacity)
		{
			int newcapacity = _capacity == 0 ? 4 : _capacity * 2;
			int* tmp = (int*)realloc(_a, sizeof(int) * newcapacity);
			if (tmp == nullptr)
			{
				perror("realloc error!");
				exit(-1);
			}
			_a = tmp;
			_capacity = newcapacity;
		}
	}
	void Push(int x)
	{
		CheckCapacity();
		_a[_top++] = x;
	}
	void Pop()
	{
		assert(_top > 0);
		_top--;
	}
	int Top()
	{
		return _a[_top - 1];
	}
	bool Empty()
	{
		return _top == 0;
	}
	void Print()
	{
		while (!Empty())
		{
			cout << _a[_top - 1] << endl;
			Pop();
		}
	}
};

struct Queue
{
    //此处没有Queue的构造函数
	Stack st1;
	Stack st2;
};


int main()
{
	Queue q;
	return 0;
}

 

  • C++11规定可以在类中的声明中给缺省值,例如:
class Date
{
public:

	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
private:
	int _year = 1;
	int _month = 1;
	int _day = 1;
};


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

  •  总的来说你可以根据是否需要构造函数来决定是否需要编写构造函数;
  • 通常情况下都是需要你自己编写构造函数的;
  • 特别注意在构造函数的时候虽然构成函数重载,但是切忌全缺省参数和无参数的构造同时出现,不然会发生编译错误。

2.3 构造函数总结

  1. 构造函数函数名与类名相同;
  2. 无返回值;
  3. 构成重载;
  4. 在对象实例化的时候自动调用构造函数;
  5. 如果自己没有编写构造函数那么编译器会帮你自动生成构造函数;
  6. 对于编译器生成的构造函数中,内置类型不会进行初始化,自定义类型会帮你自动调用他的构造函数;
  7. 如果自己编写了构造函数,那么编译器会根据函数名修饰调用属于他的构造函数;
  8. 无参的构造函数、全缺省构造参数、编译器自己生成的构造函数统称为默认构造函数;
  9. 通常情况下是需要构造函数的。

3. 析构函数

3.1 概念

  •         析构函数与构造函数相反,对象是通过构造函数来的,相反对象就是通过析构函数没的。
  •         但是对象的销毁不是析构本身完成的,这是编译器的任务,但是在销毁的同时会自动调用析构函数。

3.2 特性

  • 函数名是在类名之前加上~;
  • 无返回值无参数;
  • 若未显示定义,则系统会生成默认的析构函数,一个类只能由一个析构函数,不构成重载;
  • 对象生命周期结束,C++编译器会自动调用析构函数。
class Date
{
public:
	Date(int year,int month,int day)
	{
		this->_day = day;
		this->_month = month;
		this->_year = year;
	}

	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
	~Date()
	{
		cout << this << endl;
		cout << "~Date" << endl;
	}

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


void func()
{
	Date d1(2024,3,15);
}

int main()
{
	func();
	return 0;
}

  •  默认生成的析构函数跟构造函数类似
  • 内置类型不做处理,自定义类型的成员去调用他的析构
struct Stack
{
	int* _a;
	int _top;
	int _capacity;

	Stack()
	{
		_a = nullptr;
		_capacity = 0;
		_top = 0;
		cout << "This is Stack struct" << endl;
	}
	void CheckCapacity()
	{
		if (_top == _capacity)
		{
			int newcapacity = _capacity == 0 ? 4 : _capacity * 2;
			int* tmp = (int*)realloc(_a, sizeof(int) * newcapacity);
			if (tmp == nullptr)
			{
				perror("realloc error!");
				exit(-1);
			}
			_a = tmp;
			_capacity = newcapacity;
		}
	}
	void Push(int x)
	{
		CheckCapacity();
		_a[_top++] = x;
	}
	void Pop()
	{
		assert(_top > 0);
		_top--;
	}
	int Top()
	{
		return _a[_top - 1];
	}
	bool Empty()
	{
		return _top == 0;
	}
	void Print()
	{
		while (!Empty())
		{
			cout << _a[_top - 1] << endl;
			Pop();
		}
	}
	~Stack()
	{
		if (this->_a != nullptr)
		{
			free(this->_a);
			this->_a = nullptr;
		}
		this->_capacity = this->_top = 0;
		cout << "this is Stack Destroy" << endl;
	}
};

struct Queue
{
	Stack st1;
	Stack st2;
};

int main()
{
	Queue q;
	return 0;
}

 

在构造的时候是先构造st1,在构造st2,析构的时候是先析构st2,在析构st1,注意顺寻,栈要符合 LIFO。

3.3 析构函数总结

  • 函数名是在类名之前加上~;
  • 无返回值无参数;
  • 若未显示定义,则系统会生成默认的析构函数,一个类只能由一个析构函数,不构成重载;
  • 对象生命周期结束,C++编译器会自动调用析构函数;
  •  默认生成的析构函数跟构造函数类似;
  • 内置类型不做处理,自定义类型的成员去调用他的析构。

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

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

相关文章

如何零基础入门Prometheus

本公众号的精品教程《玩转Prometheus监控》是一套零基础的入门教程&#xff0c;基于多年实战经验编写而成&#xff0c;内容完整覆盖了产品的核心技术要点&#xff0c;适合想入门和进阶技术的朋友学习。 整个系列总共24篇课程&#xff0c;由基础知识开始&#xff0c;逐步进阶学…

复现文件上传漏洞

一、搭建upload-labs环境 将下载好的upload-labs的压缩包&#xff0c;将此压缩包解压到WWW中&#xff0c;并将名称修改为upload&#xff0c;同时也要在upload文件中建立一个upload的文件。 然后在浏览器网址栏输入&#xff1a;127.0.0.1/upload进入靶场。 第一关 选择上传文件…

webpack5零基础入门-8清空前次打包文件与处理图标字体资源

1.配置output中的clean属性为true output: {/**文件输出路径 绝对路径*///__dirname 表示当前文件的文件夹目录path: path.resolve(__dirname, dist),//所有文件的输出目录/**文件名 */filename: static/js/dist.js,//入口文件输出文件名clean: true,//在打包前将path整个目录内…

【学习笔记】红队视角下的windows应急响应

1. 上线的方法 exe上线→开360晶核的情况比较困难 2&#xff09;白加黑 接下来的讲解就是基于白加黑上线&#xff0c;看如何应对应急 2. 演示 360环境启动 shell whoami →死 -beacon 如何去查杀 看外联&#xff1a; netstat -ano 提取IP 威胁情报api调用→查是否是恶意…

【Qt】QListView 显示富文本,设置文本内容颜色

【Qt】QListView 显示富文本&#xff0c;设置文本内容颜色 文章目录 I - 控件使用II - 显示富文本III - 注意事项 I - 控件使用 Qt 的 MVC 架构为 MV &#xff0c;Controller 部分继承到了 View 里&#xff0c;View(视图) 设置 Model(模型)&#xff0c;Model 设置数据 这里使用…

设备维修带来的无限价值——易点易动设备管理系统的优势

在化工工厂中&#xff0c;设备的正常运行是保障生产顺利进行的关键。然而&#xff0c;设备难免会出现故障和损坏&#xff0c;而及时有效的设备维修对于提高生产效率和降低成本至关重要。为了解决这一问题&#xff0c;易点易动设备管理系统应运而生&#xff0c;以其卓越的功能和…

TEASEL: A transformer-based speech-prefixed language model

文章目录 TEASEL&#xff1a;一种基于Transformer的语音前缀语言模型文章信息研究目的研究内容研究方法1.总体框图2.BERT-style Language Models&#xff08;基准模型&#xff09;3.Speech Module3.1Speech Temporal Encoder3.2Lightweight Attentive Aggregation (LAA) 4.训练…

前端实例:页面布局1(后端数据实现)

效果图 注&#xff1a;这里用到后端语言php&#xff08;页面是.php文件&#xff09;,提取纯html也可以用 inemployee_index.php <?php include(includes/session.inc); $Title _(内部员工首页); $ViewTopic 内部员工首页; $BookMark 内部员工首页; include(includes/…

vue3动态组件未渲染问题

渲染问题 component动态组件写法与vue2写法一致&#xff0c;代码如下&#xff1a; <component :is"componentName"/><script setup>import { ref } from vueimport account from ./user/account.vue// 组件名称const componentName ref(account)// 点击…

Linux arrch64系统架构 py文件运行时的编码问题解决

问题&#xff1a; 因为要测试一些东西&#xff0c;所以必须有中文数据来做支撑&#xff0c;之前用的架构是x86&#xff0c;现在一个服务器的架构为arrch64&#xff0c;下列编码都挨个都进行声明&#xff0c;但是无法解决问题&#xff0c;总是报错 # -*- coding: gbk -*- # -*…

数组的大小与元素的个数

一、数组的大小 数组一旦声明&#xff0c;大小就确定了&#xff0c;无论元素是否填充 以大括号声明的数组&#xff0c;数组大小和大括号中元素的数量是一致的 以双引号字符串声明的字符数组&#xff0c;数组大小比字符的个数多一个 sizeof(数组名)得到的是元素类型所占字节…

一行代码极速部署:打造面向开发者的流计算平台

作者&#xff1a;Yingjun Wu TL;DR. curl https://risingwave.com/sh | sh在2021年初&#xff0c;我创立了RisingWave&#xff0c;目标是推广流计算技术的普及。在过去的三年中&#xff0c;我不断的向市场布道RisingWave&#xff0c;希望RisingWave能够在流计算这一市场中占…

精简版 Obsidian 图床配置 PicGo+ gitee

精简版 Obsidian 图床配置 PicGo gitee 图床的作用 图床&#xff08;Image Hosting Service&#xff09;是一种在线服务&#xff0c;用于存储和托管用户上传的图片文件。用户可以将图片上传到图床服务器&#xff0c;并获得一个可访问的图片链接&#xff0c;然后可以在网页、博…

【Stable Diffusion】入门-01:原理简介+应用安装(Windows)+生成步骤

【Stable Diffusion】入门&#xff1a;原理简介应用安装&#xff08;Windows&#xff09;生成步骤 原理简介应用安装 原理简介 稳定扩散生成模型(Stable Diffusion)是一种潜在的文本到图像扩散模型&#xff0c;能够在给定任何文本输入的情况下生成照片般逼真的图像。 应用安…

谷歌的后量子密码学威胁模型

1. 引言 若现在不使用量子安全算法来加密数据&#xff0c;能够存储当前通信的攻击者最快十年内就能对其解密。这种先存储后解密的攻击是当前采用后量子密码学 (post-quantum cryptography&#xff0c;PQC) 背后的主要动机&#xff0c;但其他未来的量子计算威胁也需要一个深思熟…

macOS - 获取硬件设备信息

文章目录 1、CPU获取方式 一&#xff1a; system_profiler获取方式二&#xff1a;sysctl&#xff0c; machdepmachdep 2、内存3、硬盘4、显卡5、声卡6、光驱7、系统序列号8、型号标识符9、UUID 等信息 10. 计算机名称 1、CPU 获取方式 一&#xff1a; system_profiler % syst…

CKA认证之Etcd备份与恢复

题目介绍&#xff1a; 资料参考&#xff1a; https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/configure-upgrade-etcd 解题&#xff1a; 1、备份 #参考模板列出 etcdctl 可用的各种选项。 #例如&#xff0c;你可以通过指定端点、证书和密钥来制作快照&#xff0…

计算机视觉——目标检测(R-CNN、Fast R-CNN、Faster R-CNN )

前言、相关知识 1.闭集和开集 开集&#xff1a;识别训练集不存在的样本类别。闭集&#xff1a;识别训练集已知的样本类别。 2.多模态信息融合 文本和图像&#xff0c;文本的语义信息映射成词向量&#xff0c;形成词典&#xff0c;嵌入到n维空间。 图片内容信息提取特征&…

大语言模型提示词技巧

LLM&#xff08;Large Language Model&#xff09;大语言模型时代&#xff0c;提示词&#xff08;Prompt&#xff09;很重要&#xff0c;而改进提示词显然有助于在不同任务上获得更好的结果。这就是提示工程背后的整个理念。 下面我们将介绍更高级的提示工程技术&#xff0c;使…

【办公类-40-01】20240311 用Python将MP4转MP3提取音频 (家长会系列一)

作品展示&#xff1a; 背景需求&#xff1a; 马上就要家长会&#xff0c;我负责做会议前的照片滚动PPT&#xff0c;除了大量照片视频&#xff0c;还需要一个时间很长的背景音乐MP3 一、下载“歌曲串烧” 装一个IDM 下载三个“串烧音乐MP4”。 代码展示 家长会背景音乐: 歌曲串…