C++类与对象(二)——构造函数与析构函数
文章目录
- 一.类的默认6个成员函数
- 二.构造函数
- 1.引例
- 2.构造函数的概念及特性
- 三.析构函数
- 😋析构函数的特性
前言:
上篇文章初步认识了类以及类的相关知识,本篇将继续深入学习类与对象——类的默认6个成员函数:
一.类的默认6个成员函数
上一章我们说到,如果一个类中什么成员都没有,那么这个类就叫空类。这么说其实不是很严谨,因为当我们定义好一个,不做任何处理时,编译器会自动生成以下6个默认成员函数:
- 默认成员函数:如果用户没有手动实现,则编译器会自动生成的成员函数:
- 构造函数:主要完成初始化工作
- 析构函数:主要完成清理工作
- 拷贝构造:使用已经存在的一个对象初始化创建另一个对象
- 复制重载:把一个对象赋值给另一个对象
- 取地址重载:普通对象取地址操作
- 取地址重载(
cons
t):const
对象取地址操作
二.构造函数
1.引例
在C语言阶段,我们在使用栈的数据结构的时候,每当创建一个Stack
对象,首先得调用它的初始化函数StackInit
来初始化对象。
typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}St;void StackInit(St* ps);
//……
int main()
{St s;StackInit(&s);return 0;
}
在每次使用前,都要先初始化,这样显得太麻烦而且容易遗忘。在C++
中,构造函数为我们很好的解决了这一问题。
2.构造函数的概念及特性
构造函数是一个特殊的成员函数。构造函数虽然叫构造,但是其主要作用并不是开辟空间创建对象,而是初始化对象。
构造函数具有以下特性:
1. 函数名与类名相同
2. 无返回值
3. 对象实例化时,编译器自动调用对应的构造函数
4. 构造函数可以重载
举例:
class Data
{
public:// 无参的构造函数Data(){}// 带参的构造函数Data(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};void TestData()
{// 调用无参构造函数Data d1;// 调用带参的构造函数Data d2(2023, 5, 3);
}
注意:
创建对象时编译器会自动调用构造函数,若是调用无参的构造函数,则无需在对象后加
()
,否则会产生歧义:编译器无法确定是在声明函数还是在创建对象。
错误示例:
// 错误示例
Data d3();
5. 如果类中没有显示定义的构造函数,则C++
编译器会自动生成一个无参的默认构造函数,一旦用户显示定义编译器将不再生成
class Data
{
public:// 若用户没有显示定义,则编译器自动生成//Data(int year, int month, int day)//{// _year = year;// _month = month;// _day = day;//}
private:int _year;int _month;int _day;
};
6. 默认生成构造函数,对内置成员不作处理,对自定义类型成员,会调用它的默认构造函数
C++
把类型分为内置类型(基本类型)和自定义类型。内置类型就是语言提供的基本数据类型,如:int
,char
,double
……,自定义类型就是我们使用的class
,struct
,union
等自己定义的类型
举例:
默认构造函数对内置类型:
class Data
{
public:void print(){cout << _year << '-' << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;
};
void TestData1()
{Data d1;d1.print();
}int main()
{TestData1();return 0;
}
运行结果:
如图所示,默认构造函数未对内置类型做处理。
默认构造函数对自定义类型:
class stack
{
public:// stack的默认构造函数stack(){cout << "stack" << endl;_a = nullptr;_top = _capacity = 0;}
private:int* _a;int _top;int _capacity;
};class queue
{
public:// 不对queue的构造函数做显示定义,测试构造函数
private:stack _s;
};void TestQueue()
{queue q;
}
int main()
{TestQueue();return 0;
}
运行结果:
如图所示,在创建queue
对象时,默认构造函数对自定义成员_s
做了处理,调用了它的默认构造函数stack()
- 但是这种容易混淆的使用方式让很多人感到不满,为什么要针对内置类型和自定义类型做不同的处理呢?终于,在
C++11
中针对内置类型成员变量不初始化的缺陷,又打了补丁,即:
7. 内置类型成员变量在类中声明时可以给默认值
示例:
class Date
{
public:void print(){cout << _year << '-' << _month << '-' << _day << endl;}
private:int _year = 0;int _month = 0;int _day = 0;
};void TestDate2()
{Date d2;d2.print();
}int main()
{TestDate2();return 0;
}
运行结果:
默认值:若不对成员变量作处理,则使用默认值
8. 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只有一个
示例:
class Date
{
public:// 1.无参的默认构造函数// Date()// {// ……// }// 2.全缺省的默认构造函数Date(int year = 0, int month = 0, int day = 0){_year = year;_month = month;_day = day;}void print(){cout << _year << '-' << _month << '-' << _day << endl;}
private:int _year = 0;int _month = 0;int _day = 0;
};
三.析构函数
析构函数与构造函数的特性相似,但功能恰好相反。构造函数是用来初始化对象的,析构函数是用来销毁对象的。
需要注意的是,析构函数并不是对对象本身进行销毁(因为局部对象出了作用域会自行销毁,由编译器来完成),而是在对象销毁时会自动调用析构函数,对对象内部的资源做清理(如对象
stack
中的int *a
)。
同样,有了析构函数,我们就不用担心创建对象后由于忘记释放内存而造成内存泄漏了。
示例:
class Stack
{
public:// 构造函数Stack(){}void push(int x);bool empty();int Top();// 手动释放void Destory();
private:// 成员变量int* _a;int _top;int _capacity;
};void TestStack()
{Stack s;s.push(1);s.push(2);// 手动释放s.Destory();
}
😋析构函数的特性
- 析构函数名是在类名前加~
- 无参数
- 无返回值
- 一个类只能有一个析构函数。若未显示定义,系统会自动生成默认的析构函数
- 析构函数不能重载
示例:
class Date
{
public:// 构造函数Date(){cout << "Date()" << endl;}// 析构函数~Date(){cout << "~Date()" << endl;}
private:int _year;int _month;int _day;
};void TestDate3()
{// d3生命周期结束时自动调用构造函数Date d3;
}int main()
{TestDate3();
}
运行结果:
6.编译器生成的默认析构函数,对自定义类型调用它的析构函数
示例:
class Stack
{
public:// 构造函数Stack(){cout << "stack()" << endl;_a = nullptr;_top = _capacity = 0;}// 析构函数~Stack(){cout << "~Stack()" << endl;free(_a);_a = nullptr;_top = _capacity = 0;}
private:int* _a;int _top;int _capacity;
};class queue
{
public:// 不对queue的构造函数和析构函数做显示定义// 测试默认构造函数和默认析构函数
private:Stack _s;
};void TestQueue1()
{queue q;
}int main()
{TestQueue1();return 0;
}
运行结果:
- 这里与构造函数的区别是:编译器默认生成的析构函数不像构造函数那样区分内置类型与自定义类型
这是因为:内置类型在生命周期结束时会自动销毁。而自定义类类型里可能有动态开辟的空间,因此要进行清理工作。
因此:
7.如果类中没有申请资源时,析构函数可以不写,直接用编译器生成的默认析构函数,比如Date
类;有资源申请时,一定要写,否则会造成资源泄露,比如Stack
类
本文到此结束,码文不易,还请多多支持哦!!
相关文章:
C++类与对象(二)——构造函数与析构函数
文章目录 一.类的默认6个成员函数二.构造函数1.引例2.构造函数的概念及特性 三.析构函数😋析构函数的特性 前言: 上篇文章初步认识了类以及类的相关知识,本篇将继续深入学习类与对象——类的默认6个成员函数: 一.类的默认6个成员函…...
c++标准模板(STL)(std::array)(四)
定义于头文件 <array> template< class T, std::size_t N > struct array;(C11 起) std::array 是封装固定大小数组的容器。 此容器是一个聚合类型,其语义等同于保有一个 C 风格数组 T[N] 作为其唯一非静态数据成员的结构体。不同于 C 风格数…...
vue3计算属性
计算属性 模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。推荐使用计算属性来描述依赖响应式状态的复杂逻辑 基础示例 不够好的示例 模板中使用了表达式,不够直观&…...
Java 中的访问修饰符有哪些(九)
Java 中的访问修饰符用于限制类、接口、字段和方法的访问范围,它们分别表示不同的访问控制级别。Java 中共有四种访问修饰符:public、protected、default 和 private。 public public 是最开放的访问修饰符,用于指定公共访问级别。被 publi…...
HR员工管理的三重境界:管事、管人、管心
在一个公司里,员工来来往往是常态,虽说我们不能替他们决定,但是一定是与公司的管理者有一定的关系。马云曾经说过:“一个员工离职,不外乎两种原因,一是钱没给到位;二是心里委屈了”。一句话就是…...
延迟队列与SpringBoot实战
延迟队列与SpringBoot实战 概念 延时队列,队列内部是有序的,最重要的特性就体现在它的延时属性上,延时队列中的元素是希望在指定时间到了以后或之前取出和处理,简单来说,延时队列就是用来存放需要在指定时间被处理的元素的队列 …...
【算法】九键输入法
题目: 输入数字字符串, 输出这串字符对应的九键输入法有可能出现的所有情况 算法: 定义了一个全局变量 g_numStr,其中存储了每个数字对应的字母。定义了一个递归函数 str_combine,用于将每个数字对应的字母进行组合。str_combin…...
jvm之类加载器
写在前面 当我们通过javac命令将java源代码编译为Java字节码后,必须通过类加载器将其加载到jvm中才能运行,所以类加载器是jvm中非常重要的一个组成部分,本文我们就一起来看下吧! 1:类的生命周期 类的生命周期如下图…...
Chapter4:频率响应法(上)
第四章:频率响应法 Exercise4.1 已知微分网络和积分网络电路图如下图所示,求网络的频率特性。 解: 【图 ( a ) ({\rm a}) (a)微分网络】 由微分网络电路图可得:...
【6. 激光雷达接入ROS】
欢迎大家阅读2345VOR的博客【6. 激光雷达接入ROS】🥳🥳🥳 2345VOR鹏鹏主页: 已获得CSDN《嵌入式领域优质创作者》称号👻👻👻,座右铭:脚踏实地,仰望星空&#…...
Java 基础进阶篇(三)—— 面向对象的三大特征之二:继承
文章目录 一、继承概述二、内存运行原理 ★三、继承的特点四、继承后:成员变量和方法的访问特点五、继承后:方法重写六、继承后:子类构造器的特点七、继承后:子类构造器访问父类有参构造器八、this、super 总结 一、继承概述 Jav…...
[angstromctf 2023] 部分
这个比赛打了个开头就放弃了,最近放弃的比较多,国外的网太慢,国内的题太难。 Crypto ranch 这题直接给出密文这提示 rtkw{cf0bj_czbv_nvcc_y4mv_kf_kip_re0kyvi_uivjj1ex_5vw89s3r44901831} Caesar dressing is so 44 BC... 然后是加密程序…...
死信队列
死信队列 死信的概念 先从概念解释上搞清楚这个定义,死信,顾名思义就是无法被消费的消息,字面意思可以这样理解,一般来说,producer 将消息投递到 broker 或者直接到queue 里了,consumer 从 queue 取出消息…...
基于YOLOv5的目标检测系统详解(附MATLAB GUI版代码)
摘要:本文重点介绍了基于YOLOv5目标检测系统的MATLAB实现,用于智能检测物体种类并记录和保存结果,对各种物体检测结果可视化,提高目标识别的便捷性和准确性。本文详细阐述了目标检测系统的原理,并给出MATLAB的实现代码…...
使用ChatGPT工具阅读文献的实战教程
大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…...
实训笔记1
实训笔记 第一天 1.安装tomcat或者其他大数据开发的路径不含中文及空格 2.和同开发 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FoApp1oX-1683039421826)(C:\Users\18249\AppData\Roaming\Typora\typora-user-images\image-20230422110823748…...
CCD视觉检测设备如何选择光源
CCD视觉检测设备的机器视觉系统对光源的要求很高,光源是决定图像质量的一个重要因素。那么,我们就来看看CCD图像加网设备和机器视觉系统光源的选择点——CCD图像加网设备。 CCD视觉检测设备机器视觉系统光源选择要点: 1. 对比度:…...
基于协同过滤的旅游推荐系统设计与实现(论文+源码)_kaic
1 绪论 1.1 研究背景及意义 1.2 国内外研究现状 1.3 研究目标与意义 1.4 主要研究工作 2 相关理论介绍 2.1HTML与JavaScript 2.2 MySQL数据库 2.3 协同过滤算法简介 3 系统分析与设计 3.1 系统需求分析 3.1.1 功能性需求 3.1.2 安全性需求 3.2 系统总体架构 3.3 功能模块设计 3…...
代码随想录补打卡 746 使用最小花费爬楼梯
代码如下 func minCostClimbingStairs(cost []int) int { dp : make([]int,len(cost)1) //思路:设置一个花费数组dp,dp数组的长度等于之前的cost在加上1(1为楼顶元素) dp[0] 0 dp[1] 0 for i : 2 ; i < len(c…...
有理函数的不定积分习题
前置知识:有理函数的不定积分 习题 计算 ∫ x 3 1 x 4 − 3 x 3 3 x 2 − x d x \int \dfrac{x^31}{x^4-3x^33x^2-x}dx ∫x4−3x33x2−xx31dx 解: \qquad 将被积函数的分母因式分解得 x 4 − 3 x 3 3 x 2 − x x ( x − 1 ) 3 x^4-3x^33x^2-xx…...
PS滤镜插件-Nik Collection介绍
PS滤镜插件-Nik Collection介绍 什么是Nik CollectionNik Collection都包含什么? 什么是Nik Collection Nik Collection是一款PS滤镜插件套装,其包含了八款PS插件,功能涵盖修图、调色、降噪、胶片滤镜等方面。Nik Collection 作为很多摄影师…...
力扣刷题2023-05-04-1——题目:2614. 对角线上的质数
题目: 给你一个下标从 0 开始的二维整数数组 nums 。 返回位于 nums 至少一条 对角线 上的最大 质数 。如果任一对角线上均不存在质数,返回 0 。 注意: 如果某个整数大于 1 ,且不存在除 1 和自身之外的正整数因子,…...
【Java笔试强训 2】
🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 一、选择题 二、编程题 🔥排序子…...
术数基础背诵口诀整理
物象对应 五行方位天干神兽季节气候星宿生成数脏器木东甲乙青龙春风岁八肝火南丙丁朱雀夏热荧惑七心土中戊己?长夏湿镇五脾金西庚辛白虎秋燥太白九肺水北壬癸玄武冬寒辰六肾 口诀:东方甲乙青龙木,南方丙丁朱雀火,戊己勾陈腾蛇土&…...
Linux 基础语法 -2
如果我们以后再Linux当中 写了一些命名,导致程序我们不能进行操作了,如这个死循环: 他就会一直输出 "hello Linux" ,我们就使用 ctrl c 来终止因为程序或者指令异常,而导致我们无法进行指令输入ÿ…...
深度学习框架发展趋势
深度学习方法的发展是推动深度学习框架进步的最大动力,因此深度学习框架的功能和设计应顺应 算法和模型的发展趋势: 第一,易用性。深度学习领域仍处于快速发展期,参与者和学习者不断增加,新模型大量提出。因 此&#…...
Mysql为json字段创建索引的两种方式
目录 一、前言二、通过虚拟列添加索引(Secondary Indexes and Generated Columns)三、多值索引(Using multi-valued Indexes)四、官网地址 一、前言 JSON 数据类型是在mysql5.7版本后新增的,同 TEXT,BLOB …...
cassandra数据库入门-4
插入数据 在表中创建数据 您可以使用命令 INSERT 将数据插入表中一行的列中。 下面给出了在表中创建数据的语法。 INSERT INTO <tablename> (<column1 name>, <column2 name>....) VALUES (<value1>, <value2>....) USING <option> 例子…...
微服务学习——分布式搜索
初识elasticsearch 什么是elasticsearch elasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容。 elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)。被广泛应用在日志数据分析、实时监控等领域…...
ChatGPT根据销售数据、客户反馈、财务报告,自动生成报告,并根据不同利益方的需要和偏好进行调整?
该场景对应的关键词库(24个): 汇报对象身份(下属、跨部门平级、领导)、销售数据(销售额、销售量、销售渠道)、财务报告(营业收入、净利润、成本费用)、市场分析…...
专业科技网站建设/百度框架户开户渠道
vi的使用--使用vi查找和替换 vi提供了几种定位查找一个指定的字符串在文件中位置的方法。同时还提供一种功能强大的全局替换功能。 1. 查找一个字符串 一个字符串是一行上的一个或几个字符。 为查找一个字符串,在vi命令模式下键入“/”,后面跟要查找的…...
iis7安装wordpress/视频号怎么付费推广
软件工程-软件维护/系统维护 系统可维护性 评价指标 可理解性可测试性可修改性 系统维护类型 改正性维护适应性维护预防性维护完善性维护 tip:完善性维护占半壁江山 系统文档 开发文档:技术员编写,与开发相关产品文档:与用…...
廊坊网站建设精灵/外贸网站推广的方法
swal()方法是一个提示框;swal({title: "",text: "请扫描用户手机上的付款码",type: "input",showCancelButton: true,closeOnConfirm: false,cancelButtonText: "取消",confirmButtonText: "确认",imageUrl: &qu…...
苏州招聘网站建设/杭州百度推广开户
题解在下已经写过一次了,所以就不再写了,下面只有代码 题解下载(1):http://pan.baidu.com/s/1hsAUjMs 题解下载(2):http://pan.baidu.com/s/1mhC7EYk A 卿学姐与公主 代码 #include <iostream> #include <cstdio> #include <a…...
网站 ip地址是什么/链接下载
正文 此处以Quartus II 11.1和Notepad v5.9.6.2为例。 1. 使用QII自动调用Notepad来打开HDL、sdc、txt等文件;并且可以在报错的时候,Notepad可以直接高亮所报错的行(此模式下,Notepad最大化后效果最佳)。 方法…...
要服务网站建设/优化网站链接的方法
DDD进行调试 介绍标题:嵌入式开发中使用DDD进行调试2008-01-17 19:57:28在嵌入式程序开发过程中,程序员要进行大量的调试,以此验证程序的正确性,修改潜在的错误。调试器对于程序员来说是不可或缺的必备工具。在Linux环境 中&#…...