【C++】类与对象(2)

news2024/11/24 19:25:15

【C++】类与对象(2)

作者:爱写代码的刚子
时间:2023.5.4
本篇博客有关构造函数、析构函数、拷贝构造的知识,由于本篇博客可能比较详细,还剩一些内容没介绍,所以我将剩余的知识放在下一篇博客。

目录

  • 【C++】类与对象(2)
      • 类的6个默认成员函数
      • 构造函数
          • 特性
      • 析构函数
      • 拷贝构造函数
          • 特征

类的6个默认成员函数

在这里插入图片描述

构造函数

能否在对象创建时,不去调用成员函数,就能将信息设置进去呢?于是就有了构造函数。
构造函数:构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,保证每个数据成员都有 一个合适的初始值,并且在对象的生命周期内只调用一次。

特性

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

  1. 函数名与类名相同。

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

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

  4. 构造函数可以重载。(可以有多个形式的构造函数)
    在这里插入图片描述

  5. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。
    注意:
    自动生成的无参的默认构造函数不能很好地初始化,如图:
    在这里插入图片描述

  • 编译器默认生成的构造函数对于内置类型不做初始化,对于自定义类型, 则调用自定义类型的构造函数(不是所有的编译器都这样,vs2019中如果仅含内置类型,编译器不做初始化,如果含有自定义类型,编译器才会将内置类型初始化为0,自定义类型调用自己的构造函数)

总结:只要成员变量含内置类型,必须自己实现构造函数进行初始化,不用编译器生成的(为了统一,因为不同编译器处理不同),如果成员变量全都为自定义类型,可以考虑让编译器自动生成默认构造函数,前提是这些自定义类型都定义了默认构造函数。

对于编译器初始化不统一在这里举一个例子:
vs2019中:
在这里插入图片描述
VS2019编译器进行了优化,当类的成员变量中有指针类型时,会将所有的普通成员变量初始化。
vs2017中:
在这里插入图片描述
即使成员变量中含有指针类型,编译器也不会进行初始化。
所以编译器之间的初始化并不统一。

注:所以这相当于C++的一个缺陷(编译器对于成员变量的初始化不统一),针对这个缺陷,C++11标准发布的时候打了一个补丁,对于成员变量可以给缺省值。

  1. 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认成员函数。
    注意:无参的构造函数和全缺省的构造函数只能存在一个,若同时存在调用将会产生冲突:
    在这里插入图片描述
  • 不传参编译器不知道调用无参的构造函数或全缺省的构造函数,因为两者在语法上形式相同,无法区分。
  1. C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语法已经定义好的类型:如int/char…,自定义类型就是我们使class/struct/union自己定义的类型,编译器生成默认的构造函数会对自定类型成员_t调用的它的默认成员函数。

  2. 成员变量的命名风格。一般在成员变量前加_或成员变量后加_。

注意:无参数传递的构造函数在写法上不加(),防止语法上和函数的声明发生冲突。

test a;//正确
test a();//错误

析构函数

析构函数:对象在销毁时会自动调用析构函数,完成类的一些资源清理工作。(可以利用析构函数来防止内存泄漏,局部对象的销毁工作一般由编译器完成的)
析构函数是特殊的成员函数。
特征:
其特征如下:

  1. 析构函数名是在类名前加上字符 ~。
  2. 无参数无返回值。
  3. 一个类有且只有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。(析构函数不能重载)
    同构造函数,系统自动生成的默认析构函数并不能很好地进行资源的清理工作(析构函数对内置类型不做处理,如果有自定义类型,自定义类型将调动自己的析构函数)所以当类里面只有自定义类型时可以使用系统自动生成的析构函数,其他情况需要我们自己实现析构函数
  4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。
  5. 编译器生成的默认析构函数,对会自定类型成员调用它的析构函数析构函数防止内存泄漏:
    在这里插入图片描述
    对象生命周期结束后调用析构函数将空间销毁,不用手动进行操作。

总结:
1.一般情况下,有动态申请资源,就需要显示写析构函数释放资源
2.没有动态申请的资源,不需要写析构
3.需要释放资源的成员都是自定义类型,不需要写析构
4.析构函数满足后进先出,后定义的先析构

拷贝构造函数

拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。

特征
  1. 拷贝构造函数是构造函数的一个重载形式。
  2. 拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用。(自定义类型传参(如果是传值传参)是必须要调用拷贝构造的,内置类型就是直接拷贝)
    在这里插入图片描述

拷贝构造函数内的参数最好使用const修饰,防止拷贝后破坏了原来的对象。
补充:(上面图片里使用this指针是防止产生歧义,左边的b可以是test类型的b或类成员变量的b,这里编译器显示为前者,所以不加this会报错)
3. 若未显示定义,系统生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝我们叫做浅拷贝,或者值拷贝。(对于内置类型按照字节序拷贝,对于自定义类型将调用自己的拷贝构造函数
4. 编译器生成的默认拷贝构造函数不能运用于所有场景

总结:test a2(a1);语句中a2传给了this指针,a1作为了参数,a1要使用引用类型来接收(构成)
1.内置类型成员完成值拷贝/浅拷贝。
2.自定义类型会调用它自己的拷贝构造。
3.C++中Date和MyQueue不用写拷贝构造(已经自己实现了)
4.C++中Stack需要自己实现拷贝构造
5.拷贝函数使用引用参数能大大减少拷贝次数

  • 注意:内置类型貌似可以不用写拷贝构造了,但是真的是这样吗?
    这里有个大坑,如果成员变量只是像日期一样的普通内置类型,的确可以不用写拷贝构造函数,如果内置类型有指针,只是单纯的拷贝地址,拷贝出来的类里的指针相同,指向同一块空间,实际上并没有进行真正意义上的拷贝,这两个类里的指针对同一块空间进行操作,很容易出现问题。(1.如析构时可能析构两次,可能会释放两次空间,发生报错2.一个修改会影响另一个)
  • 所以为了避免以上的错误,我们可以自己实现深拷贝(深拷贝有很多应用场景,下面只举一个例子,之后会介绍)
    如果成员变量里有使用malloc开辟了一块空间,这时我们不能单纯地指针拷贝,应该开辟一块同样大小的空间,同时将该空间里面的数据也进行拷贝。(memcpy函数)

本篇完结

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

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

相关文章

探究Spring中Bean的线程安全性问题

前言 今天同事笑嘻嘻的凑过来,问了我一个问题:spring中的bean是线程安全的吗?。我内心一想肯定是安全的,毕竟这样多项目在用。但是转念一想,他那贱兮兮的表情,多半是在给我挖坑。于是我自信的回答他&#x…

如何在 DigitalOcean 中部署 ONLYOFFICE 文档

现在您可使用通过 DigitalOcean 市场提供的一键式应用在 DigitalOcean 云架构中轻松部署 Docker 版本的 ONLYOFFICE 文档。 一键式应用是一个包含所有必要预配置组件的镜像,可用于便捷地在运行有 Ubuntu OS 的 DigitalOcean 服务器上部署 ONLYOFFICE: D…

单元测试~

文章目录 单元测试Junit单元测试框架 单元测试 Junit单元测试框架

客户端无法连接docker启动的nacos-config服务

nacos踩坑记录: 基于镜像仓库教程 : https://hub.docker.com/r/nacos/nacos-server 在虚拟机启动了nacos服务,控制台可以正常打开.但是客户端无法正确连接.但是又没有明确的异常信息,只有一行warn日志:There is no content for NacosPropertySource from dataId[application.ym…

面试必问的【网络io】,1.5W字超全面总结

今天分享的基本上一面试就会被问的网络IO。文中涉及的代码部分不太重要,重要的是对这概念的理解。在看文章之前大家也可通过下面的思维导图看看自己是否能回答出来。 ​大纲 1 阻塞与非阻塞--开胃菜 阻塞 我们知道在调用某个函数的时候无非就是两种情况&#xff0…

1553B总线与FlexRay总线的协议转换

1553B总线与FlexRay总线的协议转换 背景技术: 某一1553B数字时分系统,存在响应型和周期型两种类型的指令传输。如果在1553B总线上传输周期型指令,不仅会造成BC->RT调度指令的大量重复,还存在BC设备和RT设备时间不同步的风险&a…

API 渗透测试从入门到精通系列文章(下)

导语:在本系列文章的前面一部分我们从使用 Postman 开始,创建了集合和请求,并通过 Burp Suite 设置为了 Postman 的代理,这样我们就可以使用 Burp 的模糊测试和请求篡改的功能。 在本系列文章的前面一部分我们从使用 Postman 开始…

Unity 后处理(Post-Processing) -- (3)挑战:创建局部后处理Volume

为何使用局部Volume 在前面两节中,我们使用了一个Global Volume来应用后处理,其作用范围是整个场景。有些时候,我们需要实现当角色靠近某个地点后,进行一些特殊的后处理。这时我们就需要使用Local Volume来实现这个功能。 举个例子…

网络安全就业岗位与薪资

前段时间,知名机构麦可思研究院发布了《2022年中国本科生就业报告》,其中详细列出近五年的本科绿牌专业,*信息安全位列第一。* 对于网络安全的发展与就业前景已经说过很多,它是收入较高的岗位之一,在转行领域也占据着…

大津算法ostu

大津算法是一种自适应图像二值化方法。 它以最大化类内距离或最小化类间距离为优化目标,将图像从某一亮度阈值分为前景/背景。 其基本原理示意图如下: 1.前言 为了深入介绍此算法,先说明一些背景知识。 1.1 数据可分性 数据可分性通常使…

【视频解读】动手学深度学习V2_01课程介绍

1.概述 这门课程主要介绍深度学习经典和最新模型。从最简单、最老的80年代的Lenet,讲到计算机视觉比较流行的Resnet,以及经典的时序模型LSTM以及最近比较流行的BERT。当然我们在讲深度学习时,我们离不开机器学习,机器学习的很多基础知识是我们需要的&…

关于OLED屏的笔记

OLED即有机发光管(Organic Light-Emitting Diode,OLED)。OLED显示技术具有自发光、广视角、几乎无穷高的对比度、较低功耗、极高反应速度、可用于绕曲性面板、使用温度范围广、构造及制程简单等有点,被认为是下一代的平面显示屏新兴应用技术。 OLED显示和传统的LCD显…

英文论文(sci)解读复现【NO.6】ASFF-YOLOv5:基于多尺度特征融合的无人机图像道路交通多元检测方法

此前出了目标检测算法改进专栏,但是对于应用于什么场景,需要什么改进方法对应与自己的应用场景有效果,并且多少改进点能发什么水平的文章,为解决大家的困惑,此系列文章旨在给大家解读发表高水平学术期刊中的 SCI论文&a…

Xceed Ultimate Suite 22.3 Crack

Xceed Ultimate Suite 22.3 Crack  Xceed Ultimate Suite是最完整的包括所有用户的工具,并设置所有Xceed和计算机连接以生成书面数据。Xceed Ultimate Suite还为用户提供了140多个预先编写的比较。 Xceed Ultimate Suite公司的功能和特点: -包括.NET在内…

Linux shell脚本 扩展补充示例

通过变量切片、获取变量长度、产生随机数、合并字符串 最后生成随机密码 变量切片、获取变量长度 [xuexue ~]$ a1234567890 [xuexue ~]$ echo $a [xuexue ~]$ echo ${a} [xuexue ~]$ echo ${#a} #获取变量长度 [xuexue ~]$ echo ${a:3:3} #切片,第4个开始获取三个…

力扣题库刷题笔记646-最长数对链

1、题目如下: 2、题解思路代码实现: 本题算是到目前为止,代码能读懂,但是思路并不能完全理解的代码(大概能理解,但是无法完全描述,不看题解不能做出),涉及到贪心和排序。…

07_Uboot顶层Makefile分析_make xxx_defconfig

目录 make xxx_defconfig 过程 Makefile.build 脚本分析 scripts_basic 目标对应的命令 %config 目标对应的命令 make xxx_defconfig 过程 在编译uboot之前要使用"make xxx_defconfig"命令来配置uboot,那么这个配置过程是如何运行的呢?在顶层Makefile中有如下代…

C++类模板

类模板和函数模板语法相似&#xff0c;在声明模板template后面加类&#xff0c;此类称为类模板. 类模板作用&#xff1a; 建立一个通用类&#xff0c;类中的成员 数据类型可以不具体制定&#xff0c;用一个虚拟的类型来代表。 语法&#xff1a; template<typename T> …

深入解析PyTorch中的模型定义:原理、代码示例及应用

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

【基础算法】大数运算问题

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…