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

news2024/9/27 23:22:58

###前言:此文主要介绍C++中的六种默认成员函数;默认的意思就是我们不写编译器会自动生成;这些函数在类里面自动生成;但是我们也可以自己写;学习这几种默认成员函数从两个方面入手:

(1)编译器自动生成时,这些函数会做什么?有哪些行为?这些行为是否满足我们的需求?

(2)我们自己写时,要怎么写才能满足我们的需求?


一、构造函数

构造函数名为构造,但是它的作用却不是去构造的;构造函数 ,        的作用是初始化,可以把它想象成Init去理解;构造函数在我们用类实例化对象时发挥作用,去初始化对象里面的一些属性。

构造函数的几个性质:

(1)一个类的构造函数的名称和这个类一样;构造函数没有返回值,函数名前面也不要写void;

(2)构造函数支持重载,也就是说一个类里面可以有多个构造函数;

(3)构造函数开始作用时间是实例化对象的时候,并且自动调用;

(4)我们不定义构造函数时,编译器会自己在类里面生成一个无参的默认构造函数;当我们自己定义构造函数时,编译器就不会自动生成了;

(5)构造函数分为无参、带参、和缺省参数几种;默认构造函数是可以不传实参的构造函数,具体是:我们自己定义的无参、全缺省或者编译器自动定义的无参构造函数。默认构造函数在一个类中只能出现一种,原因:我们不定义时,自动生成无参的,那么就是一种;我们自己定义时,若是定义无参和全缺省两种,那么调用时不知道调用哪一个(不传参这两者都鞥被调用),只能写两者之一;(注意:我们自己定义的无参和编译器定义的无参是有区别的,最主要的区别在于给成员变量初始化的值不同);

(6)编译器自动生成的默认构造函数对内置类型的成员变量的初始化是未定义的;对自定义类型的成员变量的初始化则调用这个成员变量自己的构造函数;

###代码示例1:

#include<iostream>
using namespace std;

class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	void Print()
	{
		cout << _year << '/' << _month << '/' << _day << endl;
	}
	//构造函数
	//1、无参
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	//2、带参
	Date(int year,int month,int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
};
int main()
{
	Date d1;//这里已经自动调用了
	d1.Print();

	Date d2(2020, 1, 1);//这是带参的写法
	d2.Print();
}

 

首先看到我们自己定义的无参和带参两种构造函数;可以观察到:构造函数名称和类名一样,并且构造函数可以重载,写法也只是类名,没有返回值和void之类的;

调用构造函数的时间是实例化对象时,那么对于无参的来说,直接实例化的同时就自动调用了无参构造函数;对于带参的来说,要在实例化时在对象的后面加上括号,括号里面写置为的初始化的值;

具体观察调用构造函数的时间:

还未实例化:

实例化 d1:

实例化d2:

 可以观察到构造函数是在实例化对象的同时调用的;

###代码示例2:

接下来看到我们不定义构造函数时,系统自动生成默认构造函数的过程:

class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	//不自己写构造函数

};

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

未实例化:

实例化之后:

 我们没有写构造函数,但是实例化之后d1的属性还是初始化了;初始化的是随机值;这证明了编译器自动生成的默认构造函数对对象的内置类型的成员变量的初始化是随机的。

###代码示例3:

这里主要看全缺省的默认构造函数(可以不传实参就是默认构造函数):

class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	//全缺省
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << '/' << _month << '/' << _day << endl;
	}
};

int main()
{
	//不传参时
	Date d1;
	d1.Print();
	//传参时
	Date d2(10);
	d2.Print();
	return 0;
}

###代码示例4:

当我们不写构造函数时,编译器自动生成的默认构造函数对内置类型成员变量的初始化是随机的,对自定义类型的成员变量初始化则是调用这个自定义类型的成员变量自己的构造函数,这里主要来观察系统自动生成的无参默认构造函数对自定义类型的成员变量初始化的过程:

简单示例:

class X
{
private:
	int _a;
	int _b;
public:
	X()
	{
		_a = 10;
		_b = 20;
	}
};

class Y
{
//定义两个类的自定义类型
private:
	X _A;
	X _B;
	int _c;
public:
	//不写构造函数
};
int main()
{
	Y y;
	return 0;
}

 这里定义了两个类:X、Y;X有自己的成员变量:_a   _b,并且在X中定义了一个无参构造函数;Y的属性有 类X自定义类型的_A和_B,以及一个内置类型_c ;Y中不写构造函数;

在main函数中用一个Y类实例化对象y,那么此时也会调用编译器自动生成的无参默认构造函数;我们来观察y属性的初始化的情况:

可以观察到,编译器自动生成的默认构造函数对对象初始化时,y中自定义类型的成员变量 _A和_B会调用它们自己的构造函数也就是类X中的构造函数;对于内置类型的_c,那么它的初始化是随机的。

至于若是自定义类型的属性也没有构造函数,那么它的初始化的值就是随机的。


 

二、析构函数

析构函数和构造函数的作用相反,它的作用相当于Destroy,作用是对对象中申请了资源的成员变量进行释放;至于类似于上文示例中的Date类实例化的对象,则不需要用析构函数释放,因为这个类实例化出来的对象中的属性没有申请资源,它们都是局部变量,存于栈区中,在函数结束时会自动销毁。

那么我们主要来看析构函数;

析构函数的性质:

(1)析构函数的也没有返回值,前面也不用写void ;写法区别于构造函数的就是要在前面加上 ~ ;

(2)析构函数不支持重载;当我们不写析构函数时,编译器会将自动生成一个析构函数;

(3)析构函数调用时间是在对象的声明周期结束时,一般来说就是main函数走到return 0;时调用;

(4)跟构造函数相似:我们不写析构函数时,编译器自己生成的默认析构函数对于自定义类型的成员变量,析构时会调用这些成员变量自己的析构函数;对于内置类型的成员变量不做释放处理,这些成员变量随着函数栈帧的销毁而释放;

(5)无论我们写不写析构函数,对于自定义类型得到成员变量的销毁都会调用它们自己的析构函数。

###代码示例1:

我们自己写析构函数:先看只含有内置类型的对象:

class A
{
public:
	A()
	{
		_b = 190;
	}
	~A()
	{
		_b = 0;
	}
private:
	int _b;
};
class Date
{
public:
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
		_a = (int*)malloc(sizeof(int));
	}
	//析构函数
	~Date()
	{
		free(_a);
		_a = nullptr;
		_year = _month = _day = 0;
	}
private:
	int _year;
	int _month;
	int _day;
	int* _a;
	//A _c;
};

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

实例化之后:

走玩return 0;对象生命周期结束,自动调用析构函数,进行释放,年月日的属性在栈区,函数栈帧销毁时才会真正释放。

 

我们自己定义的析构函数对自定义类型的成员变量的销毁:(取消注释自定义类型的成员变量,也就是多了一个成员变量A   _c)

实例化之后:

 销毁:

对于内置类型的成员变量的销毁调用的是它自己的析构函数; 

###代码示例2:
我们不写析构函数,看编译器自己生成的析构函数对对象中成员变量的销毁过程:

class A
{
public:
	A()
	{
		_b = 190;
	}
	~A()
	{
		_b = 0;
	}
private:
	int _b;
};
class Date
{
public:
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
		_a = (int*)malloc(sizeof(int));
	}
private:
	int _year;
	int _month;
	int _day;
	int* _a;
	A _c;
};

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

 可以得知,编译器自动生成的析构函数对内置类型的成员变量不做处理;对于自定义类型的成员变量还是调用它自己的析构函数,若是这个自定义类型的成员变量我们也没有自己写析构函数,那么对它也不做处理;


 总结:一般来讲,构造函数和析构函数我们都需要自己写;少数情况,如自定义类型的成员变量写好了构造和析构函数时,我们不用再写。实际上,都是我们自己写的,只不过一个对象作为另一个对象的成员变量时,若是我们写好了这个作为成员变量的对象的构造和析构,我们不用再在真正为对象的对象所在的类中写了而已。

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

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

相关文章

“AI大语言模型+”助力大气科学相关交叉领域实践技术应用

查看原文>>>“AI大语言模型”助力大气科学相关交叉领域实践技术应用 目录 专题一、预备知识 专题二、科研辅助专题 专题三、可视化专题——基于GPT实现 专题四、站点数据处理 专题五、WRF专题——基于GPT和Python实现 专题六、遥感降水专题——基于GPT和Python…

#java学习笔记(面向对象)----(未完结)

一基础相关知识点&#xff1a; 1. 一个对象的调用 首先我们创建一个Phone类 public class Phone {//成员变量String name;int age;String favourite;//成员方法public void myName(){System.out.println(name);}public void myAge(){System.out.println(age);}public void m…

免费写作神器,自动生成高质量文章

在当今数字化的时代&#xff0c;信息的传播和创作变得前所未有的重要。无论是企业的营销推广、个人的博客写作&#xff0c;还是学术研究报告&#xff0c;优质的文章都能发挥巨大的作用。而随着人工智能技术的飞速发展&#xff0c;免费的ai写作工具应运而生&#xff0c;为我们带…

虚拟内存惹

二、理解 虚拟内存 虚拟内存存在的原因物理地址和虚拟地址虚拟内存的其他介绍 虚拟内存存在的原因 计算机系统有两种地址&#xff1a;1、物理地址 2、虚拟地址 物理地址&#xff1a;是指真实的地址&#xff0c;是物理存在的&#xff0c;比如RAM、flash等 虚拟地址&#xff1a;…

使用相同模型相同数据集,为什么每次运行得到的损失值都不一样?

今天小编在学习 PyTorch 时,突然发现咋每次运行所得损失绘制的曲线都不一样呢&#xff1f;即使小编使用torch.manual_seed()函数固定 torch 的随机数种子每次运行的结果还是不一样&#xff0c;因此小编就写一篇文章记录一下。 数据集 本次使用的数据集是小编自定义的小型数据…

MySQL数据管理 - 查询语句

文章目录 查询数据1 查询指定列2 条件查询3 合并查询4 模糊查询5 聚合函数查询6 对值进行排序7 分组查询8 分页查询9 数据库关联查询1 内连接 INNER JOIN2 LEFT JOIN3 右连接 10 数据库子查询参考 查询数据 数据库最常用的操作就是查询&#xff0c;也是数据操作的基础&#xf…

MySQL基础练习题23-门店处理

目录 题目 准备数据 分析数据 方法一 方法二 题目 从分店明细表中获取门店面积。 准备数据 -- 创建库 drop database if exists db_1; create database db_1; use db_1;-- 创建门店面积表 tb_store_area CREATE TABLE tb_store_area (store_no VARCHAR(50),area…

[器械财讯]TRiCares完成近4亿融资,推动Topaz三尖瓣置换系统发展

一、融资成功助力临床研究 法国医疗器械公司TRiCares近期宣布&#xff0c;其D轮融资成功筹集5000万美元&#xff0c;所得资金将专用于支持其核心产品——经导管三尖瓣置换系统&#xff08;TTVR&#xff09;Topaz的临床研究和开发。这笔资金将用于在美国和欧盟开展临床研究&…

手持红外热成像仪的使用方法_鼎跃安全

手持红外热成像仪是一种便携设备&#xff0c;方便在现场进行温度检测和成像。他们能将物体发出的不可见红外能量转化为可见的热图像&#xff0c;直观展示物体表面的温度分布情况&#xff1b;广泛应用于电气设备维修、环保检查、应急救援等领域。接下来&#xff0c;我们一起来了…

行业原型:智慧教育线上平台-学院原型

行业原型预览链接&#xff1a; 文件类型&#xff1a;.rp 支持版本&#xff1a;Axrure RP 8 文档名称&#xff1a;智慧教育线上平台-学院 文件大小&#xff1a;1.80 MB 目录内容介绍 文档内容介绍 回复“211110” 领取

《最新出炉》系列小成篇-Python+Playwright自动化测试-66 - 等待元素至指定状态(出现、移除、显示和隐藏)

1.简介 在我们日常工作中进行UI自动化测试时&#xff0c;保证测试的稳定性至关重要。其中一个关键方面是正确地定位和操作网页中的元素。在网页中&#xff0c;元素可能处于不同的状态&#xff0c;有些可能在页面加载完成之前不在DOM中&#xff0c;需要某些操作后才会出现&…

视频剪辑sdk,跨平台部署,助力企业差异化竞争

在这个内容为王的时代&#xff0c;视频已成为连接用户、传递价值的核心媒介。无论是社交媒体、在线教育、短视频平台还是新闻资讯&#xff0c;高质量的视频内容都是吸引用户、提升用户体验的关键。然而&#xff0c;对于众多企业而言&#xff0c;如何高效、专业地处理视频内容&a…

字节跳动春节抖音视频红包系统设计与实现--图文解析

字节跳动春节抖音视频红包系统设计与实现–图文解析 原作者&#xff1a;字节跳动技术团队 原文链接&#xff1a;https://www.toutiao.com/article/7114224228030841374 原标题&#xff1a;2022 春节抖音视频红包系统设计与实现 我们做了什么 业务背景 在春节活动期间&…

洛谷 P10034 「Cfz Round 3」Circle

[Problem Discription] \color{blue}{\texttt{[Problem Discription]}} [Problem Discription] [Solution] \color{blue}{\texttt{[Solution]}} [Solution] 这是道好题。 建图&#xff0c;对每一个 i → p i i \to p_{i} i→pi​ 都建立一个有向边&#xff0c;就可以得到一个…

记一次学习--[网鼎杯 2018]Comment二次注入

目录 本文章只展示二次注入过程&#xff0c;后续获取flag并不展示 靶场 网站流程、密码的破解和目录的查询以及对于源代码获取 密码暴力破解 网站目录扫描 网站源代码获取 网站流程 尝试注入 注入代码 本文章只展示二次注入过程&#xff0c;后续获取flag并不展示 靶场…

IntelliJ IDEA 2024.2 夏季大版本发布,不得不说,更强了!

因 CSDN 上传大小限制&#xff0c;本文推荐微信中阅读&#xff0c;动图更完整&#xff0c;微信中阅读&#xff0c;请欢迎关注公众号&#xff1a;CodeFit 创作不易&#xff0c;如果你觉得这篇文章对您有帮助&#xff0c;请不要忘了 点赞、分享 和 关注&#xff0c;为我的 持续创…

Katalon Studio 使用教程——自动获取元素定位功能

这个功能很实用&#xff0c;简单来讲可以形容为&#xff0c;想要哪里点哪里&#xff0c;so easy。 比如你想定位某个输入框&#xff0c;只需要按住【Alt】&#xff0c;点一下输入框&#xff0c;系统就自动记录下来这个输入框叫什么&#xff0c;它的xpath是什么。你想要按钮就点…

arXiv2024.8.6 | LLaVA-OneVision:Easy Visual Task Transfer

Comment: Project Homepage: https://llava-vl.github.io/blog/2024-08-05-llava-onevision/ 论文标题&#xff1a;LLaVA-OneVision&#xff1a;Easy Visual Task Transfer 论文地址&#xff1a;https://arxiv.org/abs/2408.03326 GitHub&#xff1a;https://llava-vl.githu…

4岁小孩孤独症的表现

在儿童的成长过程中&#xff0c;孤独症&#xff08;也称自闭症&#xff09;的早期识别与干预至关重要。对于4岁的孩子而言&#xff0c;孤独症的表现可能已经开始显现&#xff0c;家长和教育者需保持高度敏感&#xff0c;以便及时采取措施。 社交互动障碍&#xff1a;4岁孤独症儿…

Stable Diffusion绘画 | 图生图-上传重绘蒙版

上传重绘蒙版&#xff0c;可以弥补局部重绘的缺点&#xff0c;能够更精细的修改画面中的指定区域 使用PS制作的蒙版图片为耳朵下方区域&#xff0c;可以为图片中的女生带上不同款式的耳环。 参数配置&#xff1a; 调整提示词&#xff1a; 生成图片如下所示&#xff1a; 调整提…