【C++】C++中的构造函数和析构函数详解

欢迎来到CILMY23的博客

本篇主题为:C++中的构造函数和析构函数详解

个人主页:CILMY23-CSDN博客

系列专栏:Python | C++ | C语言 | 数据结构与算法

感谢观看,支持的可以给个一键三连,点赞关注+收藏。


 写在前头:

本篇会从类的六个默认成员函数开始,进入构造函数和析构函数的了解。


目录

一、类的六个默认成员函数

二、构造函数

2.1 构造函数的概念

2.2 构造函数的特点

无参和有参的构造函数 

2.3 随机值的初始化 

三、析构函数

 3.1 析构函数概念

3.2 析构函数的特点 


一、类的六个默认成员函数

在上篇文章中(点击链接跳转),我们涉及到一个特殊类,这个类中什么成员都没有,其大小为1字节,我们将如果一个类中什么成员都没有,简称为空类

 例如:A1不是空类,A2是空类。

class A1
{
public:void f1(){}
};class A2{};

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

什么是默认成员函数?
默认成员函数指的是用户没有显式实现,编译器会自动生成的成员函数称为默认成员函数

 9f17fce17cac4584841ce84e604964f2.png

二、构造函数

构造函数作为类默认成员函数中特殊的成员函数,是面向对象编程中非常重要的概念,那什么是构造函数呢?

2.1 构造函数的概念

现在我们有一个简易的学生类,注意,参数类型是const char*,而不是char(因为传入的参数是常量字符串,类型为const char*)

#include<iostream>
using namespace std;class Student
{
public:void Init(const char* name,int age,const char* ID){strcpy(_name, name);_age = age;strcpy(_ID, ID);}void Print(){cout <<"学生姓名:" << _name << endl;cout <<"学生年龄:" << _age << endl;cout <<"学生学号:" << _ID << endl;}
private:char _name[20];int _age;char _ID[20];
};int main()
{Student stu1;stu1.Init("zhangsan", 21, "20001216A11");stu1.Print();return 0;
}

那我们每次初始化都要调用一个Init,或者经常忘记初始化,能否省略这个步骤呢?于是C++里就引入了构造函数这个概念。

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

2.2 构造函数的特点

构造函数是特殊的成员函数,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。 

 构造函数的特点如下:

  1. 函数名与类名相同。
  2. 无返回值。(无返回值不是void,而是不需要写)
  3. 对象实例化时编译器自动调用对应的构造函数。
  4. 构造函数可以重载

构造函数也分无参有参数类型 

无参和有参的构造函数 

例如:

class Student
{
public://无参构造函数Student(){strcpy(_name, "xxxxxx");_age = 0;strcpy(_ID, "xxxxxxx");}//有参构造函数Student(const char*name,int age,const char* ID){strcpy(_name, name);_age = age;strcpy(_ID, ID);}void Print(){cout << "学生姓名:" << _name << endl;cout << "学生年龄:" << _age << endl;cout << "学生学号:" << _ID << endl;}
private:char _name[20];int _age;char _ID[20];
};int main()
{Student stu1;//调用了无参的构造函数stu1.Print();Student stu2("zhangsan", 21, "20001216A11");//调用有参的构造函数stu2.Print();return 0;
}

 在学生类中,两个构造函数构成函数重载。在对象实例化的时候,自动调用了对应构造函数,在这个学生类,我们使用了构造函数来初始化对象,但是注意在调用无参函数的时候不加 ()。

2.3 随机值的初始化 

 我们说构造函数,是默认的成员函数,编译器一定会调用,但是它并没有初始化?

我们看个例子: 

class Student
{
public:void Print(){cout << "学生姓名:" << _name << endl;cout << "学生年龄:" << _age << endl;cout << "学生学号:" << _ID << endl;}
private:char _name[20];int _age;char _ID[20];
};int main()
{Student stu1;//调用默认的构造函数stu1.Print();return 0;
}

结果:

0dda18fd4e634997a91feab8baea281f.png它不是会初始化吗?但是为什么这里没有初始化,按道理来说,应该是根据类型不同,我们就直接赋值,比如,整型给0,浮点数给0.0……

其实C++把类型分成内置类型(基本类型)自定义类型内置类型就是语言提供的数据类型,如:int/char...,自定义类型就是我们使用class/struct/union等自己定义的类型默认生成的构造函数,对于内置类型不做处理,自定义类型会去调用它的默认构造函数

例如:

class P
{
public:P(){cout << "P()" << endl;_P = 0;}
private:int _P;
};class Student
{
public:void Print(){cout << "学生姓名:" << _name << endl;cout << "学生年龄:" << _age << endl;cout << "学生学号:" << _ID << endl;}
private:char _name[20];int _age;char _ID[20];P p1; //对自定义类型调用对应的默认构造函数
};int main()
{Student stu1;//调用默认的构造函数stu1.Print();return 0;
}

C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在类中声明时可以给默认值。 

 例如:

class Student
{
public:void Print(){cout << "学生姓名:" << _name << endl;cout << "学生年龄:" << _age << endl;cout << "学生学号:" << _ID << endl;}
private:char _name[20] = "xxxx"; //注意这里还是声明,声明给缺省值int _age = 0;char _ID[20]= "xxxxxxxx";
};int main()
{Student stu1;//调用默认构造函数stu1.Print();return 0;
}

三、析构函数

通过前面构造函数的学习,我们知道一个对象是怎么来的,那一个对象又是怎么没呢的? 

 3.1 析构函数概念

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

3.2 析构函数的特点 

析构函数是特殊的成员函数,其特点如下:

  1.  析构函数名是在类名前加上字符 ~
  2.  无参数无返回值
  3.   一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构 函数不能重载
  4.  对象生命周期结束时,C++编译系统系统自动调用析构函数。 

 学生类的析构函数:

class Student
{
public:void Print(){cout << "学生姓名:" << _name << endl;cout << "学生年龄:" << _age << endl;cout << "学生学号:" << _ID << endl;}~Student()//析构函数{cout << "~Student()" <<endl ;}
private:char _name[20]; int _age;char _ID[20];
};int main()
{Student stu1;//调用默认构造函数stu1.Print();return 0;
}

如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如 Date,我们简易的学生类;有资源申请时,一定要写,否则会造成资源泄漏,比如Stack类 。


总结:

  •  构造和析构类似初始化和销毁
  •  构造函数的主要任务并不是开空间创建对象,而是初始化对象。 
  •  调用无参函数的时候不加 ()
  •  对象实例化的时候,一定调用构造函数,否则报错
  • 全缺省构造函数和无参可能会在调用的时候出问题,并不是不可以同时存在(构成函数重载),而是调用出现歧义
  • 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。
  • 无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。(一般情况写全缺省)
  • C++11 中内置类型成员变量在类中声明时可以给默认值。 
  • 默认生成的析构函数,对于内置类型不做处理,自定义类型会去调用它的默认析构函数

感谢各位同伴的支持,本期析构函数和构造函数篇就讲解到这啦,如果你觉得写的不错的话,可以给个一键三连,点赞关注+收藏,若有不足,欢迎各位在评论区讨论。  

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

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

相关文章

社交媒体数据恢复:KaokaoTalk

KaokaoTalk数据恢复方法 一、数据恢复的基本步骤 在进行KaokaoTalk数据恢复时&#xff0c;首先需要确保你已经停止使用该设备&#xff0c;以防止新的数据覆盖丢失的数据。接下来&#xff0c;你可以按照以下步骤进行操作&#xff1a; 备份数据&#xff1a;在尝试恢复数据之前&a…

【SpringCloud】OpenFeign服务接口调用快速入门

【SpringCloud】OpenFeign服务接口调用快速入门 文章目录 【SpringCloud】OpenFeign服务接口调用快速入门1. 概述2. 引入依赖3. 配置、测试 1. 概述 官网地址&#xff1a;点击跳转 Feign是一个声明性web服务客户端。它使编写web服务客户端变得更容易。使用 Feign 创建一个接口…

第十五届蓝桥杯省赛第二场C/C++B组A题【进制】题解(AC)

解题思路 按照题意进行模拟&#xff0c;计算 x x x 的 b b b 进制过程中&#xff0c;若出现余数大于 9 9 9&#xff0c;则说明 x x x 的 b b b 进制一定要用字母进行表示。 #include <iostream> #include <cstring> #include <algorithm> #include &l…

Python | Leetcode Python题解之第49题字母异位词分组

题目&#xff1a; 题解&#xff1a; class Solution:def groupAnagrams(self, strs: List[str]) -> List[List[str]]:mp collections.defaultdict(list)for st in strs:counts [0] * 26for ch in st:counts[ord(ch) - ord("a")] 1# 需要将 list 转换成 tuple …

ubuntu下boa服务器编译运行

一.下载boa源码并解压 官网网站&#xff1a;BOA源码 点击箭头所指的位置即可下载 解压&#xff1a; tar -xvf boa-0.94.13.tar.gz 解压完成得到目录&#xff1a; 二.安装环境所缺依赖&#xff0c;否则编译会报错 sudo apt install bison sudo apt install flex 三.编译 1…

利用地理矢量数据进行路径规划

文章目录 概要绘制osm安装和编译更改配置节点运行概要 地理矢量数据通常是指包括点(如地标、位置坐标)、线(如街道、河流)和多边形(如行政区划、建筑物轮廓)这样的基本几何构造,这些都是构成空间数据的基本要素。在路径规划中,这些矢量数据可以被用来表示网络中的节点…

PC-3000 Mobile Pro: 智能手机及平板设备数据提取工具

天津鸿萌科贸发展有限公司从事数据安全业务20余年&#xff0c;在数据恢复、数据取证、数据备份等领域有丰富的案例经验、前沿专业技术及良好的行业口碑。同时&#xff0c;公司面向取证机构及数据恢复公司&#xff0c;提供数据恢复实验室建设方案&#xff0c;包含数据恢复硬件设…

Maven:配置与使用指南1

https://mvnrepository.com Maven 1.maven简介 不同模块的jar包以及同时设计的功能的微小变化版本&#xff1b; 真实的开发环境&#xff1a;我们将我们的源代码在服务器上重新编译重新打包&#xff0c;工程升级维护过程繁琐 1.Maven是一个项目管理工具&#xff0c;将项目开…

matlab回归学习

前言 所谓回归学习即预测&#xff0c;便是由已知的数据推测未知的数据&#xff0c;利用转速与转矩来推测电流。 1、数据准备 下面虚拟一组转速转矩以及电流数据。 speed [100 220 330 440 550 660]; torque [200 300 400 500 700 900]; I [400 500 603 739 821 912]; arr …

DataGrip操作Oracle

一、创建表空间 表名任意起&#xff0c;路径自己指定 -- 创建表空间 create tablespace mydb1 -- 表名 datafile E:\Code\sql\oracle\oracle_tablespace\mydb1.dbf --指定表空间路径 size 100M --指定表空间大小 autoextend on next 50M --指定一次扩充多少mb extent managemen…

万兆以太网MAC设计(7)ARP协议报文格式详解以及ARP层模块设计

文章目录 前言&#xff1a;1、ARP协议详解2、ARP工作机制 二、ARP_RX模块设计三、ARP_TX模块设计四、ARP_table模块5、仿真5.1、发送端5.2、接收端5.3、缓存表 总结 前言&#xff1a; 1、ARP协议详解 ARP数据格式&#xff1a; 硬件类型:表示硬件地址的类型。它的值为1表示以太…

ocr文字识别软件是干什么的?

OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;文字识别软件是一种能够将图像或者扫描的文档中的文字内容转换为可编辑的文本格式的软件。它的主要功能包括&#xff1a; 1. **文字提取&#xff1a;**识别图像中的文字并提取出来&#xff0…

MAVEN的安装与配置

MAVEN的安装与配置 1 简介 1.1 什么是MAVEN? Maven是一个项目构建及管理工具&#xff0c;开发团队几乎不用花多少时间就能够自动完成工程的基础构建配置&#xff0c; Maven 使用了一个标准的目录结构在不同开发工具中也能实现项目结构的统一。Maven提供了清理&#xff0c;编…

Lambda表达式特点

Lambda 表达式是 Java 8 引入的一项重要特性&#xff0c;它们提供了一种更简洁的方式来表达匿名函数。Lambda 表达式允许你将一段代码传递给方法&#xff0c;而不是显式创建一个实现了接口的匿名内部类。Lambda 表达式通常用于实现单个抽象方法的接口&#xff08;即函数式接口&…

javaEE初阶——多线程(九)——JUC常见的类以及线程安全的集合类

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 小比特 大梦想 此篇文章与大家分享多线程专题的最后一篇文章:关于JUC常见的类以及线程安全的集合类 如果有不足的或者错误的请您指出! 目录 3.JUC(java.util.concurrent)常见的类3.1Callable接口3.2 RentrantLoc…

超级好看动态视频官网源码

源码介绍 超级好看动态视频引导页源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c;重定向这个界面 效果截图 源码下载 超级好看动态…

Android IPC | Android多进程模式

前 言 关于Android的进程间通信&#xff08;即IPC&#xff09;有很多种方式&#xff0c;比如我们常用的AIDL、Socket等&#xff0c;而其中最重要而且最需要掌握的就是AIDL的使用和原理&#xff0c;简单来说它是通过Binder实现的。 关于Binder的知识点非常多&#xff0c;当我们…

三角函数与其他复杂函数在C语言中的实现:CORDIC算法、泰勒公式、查表法与math库详解

在C语言中实现三角函数&#xff0c;通常有四种主要方法&#xff1a;CORDIC算法、泰勒公式展开、查表法以及直接调用C语言的标准数学库。接下来我们将详细介绍这四种方法&#xff0c;并探讨其他可能的补充实现手段。 1. CORDIC算法 CORDIC&#xff08;Coordinate Rotation Dig…

MySQL数据库触发器

用途&#xff1a;订单表table01&#xff0c;运单表table02。 首先有订单表有记录/但是刚开始只有订单号/没有运单号&#xff1b; INSERT INTO testdb.table01 (id, orderid, transportid) VALUES(4, order04, ); 然后运单表有记录/记录有运单号。 INSERT INTO testdb.table…

你如何看待AIGC技术?

你如何看待AIGC技术&#xff1f; AIGC技术&#xff08;Artificial Intelligence Generated Content&#xff09;是指由人工智能生成的内容。它在许多领域都有应用&#xff0c;包括自然语言处理、图像生成、音频合成等。虽然这些技术可以提高效率和创造力&#xff0c;但也需要注…