构造,析构,拷贝【类和对象(中)】

P. S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。
P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。

  

在这里插入图片描述

                                           博主主页:LiUEEEEE
                                                C++专栏
                                              C语言专栏
                                            数据结构专栏
                                            排序算法专栏
                                         力扣牛客经典题目专栏

目录

  • 1、前言
  • 2、构造函数
  • 3、构造函数
  • 4、拷贝函数
  • 5、结语

1、前言


  在C++中,类拥有六个默认成员函数(使用者如果没有显式实现此函数,在C++编译过程中编译器也会自动生成),如下:

在这里插入图片描述
  本文主要讲述其中的三个默认成员函数,分别为构造函数,析构函数,和拷贝构造函数,下面进入正文。



2、构造函数


  例如Data类,其构造函数如下所示:
class Data
{
public://方法1Data(){_year = 1;_month = 1;_day = 1;}//方法2Data(int year, int month, int day){_year = year;_month = month;_day = day;}//方法3Data(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};

  根据代码块所示,构造函数的目的就是为了将类中成员变量的值进行初始化,而代码块中所展示了三种不同的写法,展示了构造函数的特征:

  1. 函数名与类名相同。
  2. 无返回值。
  3. 对象实例化时编译器自动调用对应的构造函数。
  4. 构造函数可以重载。

  方法3的使用方式为,在创建类对象时,在对象后传入想要初始化的值,例如:

	Data data(2024, 7, 2);

  而作为无参的初始化类成员,将默认调用无参数的构造函数,正如上文中提及的特征3一样。

  值得注意的是,即使构造函数可以重载,以应对不同的初始化要求,但代码块中所展示的方法3和方法1不可以同时出现,因为当使用者创建类时:

	Data data;

  
  编译器会去类中寻找使用者显式实现的无参类型构造函数,但对于全缺省类型的构造函数也可以不传递参数进行类对象的创建,此时编译器就出现了调用冲突,不知道使用者想调用的构造函数是哪一个。


  在C++中,如果使用者没有显式实现构造函数,那么C++默认生成的构造函数在调用时并不会对内置类型(编译器中自带的类型:int , double , char 等)进行初始化(主要取决于编译器,在最新版编译器中可能会将相关成员变量初始化为特定的值),但对于自定义类型,会调用其无参的构造函数(例如:全缺省的构造函数,无参的构造函数,编译器自动生成的构造函数。 注意以上三种无参构造函数在类中只能存在一个)。
  演示如下:
class Data
{
public:void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;
};int main()
{Data data;data.Print();return 0;
}

在这里插入图片描述




3、构造函数


  对于析构函数,同样以Data类为例,析构函数的功能与构造函数相反,析构函数不是完成对对象本身的销毁,局部对象的销毁工作是由编译器完成的,而对象在销毁时会自动调用析构函数,完成对象中资源的清理,类似于在实现栈时的Destroy函数。
  析构函数的特征:
  1. 析构函数名是在类名前加上字符 “ ~ ”。
  2. 无参数无返回值类型。
  3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构
    函数不能重载
  4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。

  样例如下
class Data
{
public:Data(int year = 2024,int month = 7,int day = 2){_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}~Data(){cout << "~Data()" << endl;_year = 1;_month = 1;_day = 1;}
private:int _year;int _month;int _day;
};int main()
{Data data;data.Print();return 0;
}

  因为编译器在生命周期结束时自动调用析构函数,故上述代码块中在析构函数中添加了打印语句“ cout << “~Data()” << endl; ”,其打印结果如下:
在这里插入图片描述
  可以明确的看到编译器确实调用了析构函数。

  同样的,析构函数在调用时不会对内置类型进行处理,对自定义类型的对象会调用其自己的析构函数,此处不再做演示。




4、拷贝函数


  C++中拷贝函数也称为拷贝构造函数,其主要目的是在初始化时,将某一个类对象的成员值直接拷贝给新的类对象,其使用方法如下:
	Data data1;//方法1Data data2(data1);//方法2Data data3 = data1;

  拷贝函数的特征如下:

  1. 拷贝构造函数是构造函数的一个重载形式。
  2. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。
  3. 若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按
    字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。

  那如果使用者要显式实现拷贝函数呢?其代码如下所示:
	Data(Data& d){_year = d._year;_month = d._month;_day = d._day;}

  可以看到在书写拷贝函数的代码时,参数部分使用了引用,这是因为在传递过程中我们直接将data放在了函数调用的部分,如果不使用引用的话,此处就会发生传值调用,而C++编译器默认在发生传值调用时,会先调用其拷贝函数,而我们的拷贝函数的参数是形参,就会发生无穷无尽的递归调用,而编译器在面对这种情况时会直接报错。
在这里插入图片描述
  其原理类似于在日常使用函数时我们所传递的为形参,而形参是实参的一份临时拷贝,而拷贝函数在形参处,就会发生无穷无尽的递归。


  如果使用者不显式实现拷贝函数,那么编译器会自动生成,并按照内存存储按字节序的方式进行拷贝,显式实现与不实现都是使用者可以选择的方式,具体情况按照实际需求进行选择。




5、结语


在这里插入图片描述

  十分感谢您观看我的原创文章。
  本文主要用于个人学习和知识分享,学习路漫漫,如有错误,感谢指正。
  如需引用,注明地址。

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

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

相关文章

yolov8obb角度预测原理解析

预测头 ultralytics/nn/modules/head.py class OBB(Detect):"""YOLOv8 OBB detection head for detection with rotation models."""def __init__(self, nc80, ne1, ch()):"""Initialize OBB with number of classes nc and la…

1.k8s:架构,组件,基础概念

目录 一、k8s了解 1.什么是k8s 2.为什么要k8s &#xff08;1&#xff09;部署方式演变 &#xff08;2&#xff09;k8s作用 &#xff08;3&#xff09;Mesos&#xff0c;Swarm&#xff0c;K8S三大平台对比 二、k8s架构、组件 1.k8s架构 2.k8s基础组件 3.k8s附加组件 …

深入理解ThreadLocal原理

以下内容首发于我的个人网站&#xff0c;来这里看更舒适&#xff1a;https://riun.xyz/work/9898775 ThreadLocal是一种用于实现线程局部变量的机制&#xff0c;它允许每个线程有自己独立的变量&#xff0c;从而达到了线程数据隔离的目的。 基于JDK8 使用 通常在项目中是这样…

JAVA连接FastGPT实现流式请求SSE效果

FastGPT 是一个基于 LLM 大语言模型的知识库问答系统&#xff0c;提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排&#xff0c;从而实现复杂的问答场景&#xff01; 一、先看效果 真正实流式请求&#xff0c;SSE效果&#xff0c;SSE解释&am…

全球首款商用,AI为视频自动配音配乐产品上线

近日&#xff0c;海外推出了一款名为Resona V2A的产品&#xff0c;这是全球首款商用视频转音频 (V2A) 技术产品。这项突破性技术利用AI&#xff0c;仅凭视频数据即可自动生成高质量、与上下文相关的音频&#xff0c;包括声音设计、音效、拟音和环境音&#xff0c;为电影制作人、…

Ubuntu20.04安装Prometheus监控系统

环境准备&#xff1a; 服务器名称内网IP公网IPPrometheus服务器192.168.0.23047.119.21.167Grafana服务器192.168.0.23147.119.22.8被监控服务器192.168.0.23247.119.22.82 更改主机名方便辨认 hostnamectl set-hostname prometheus hostnamectl set-hostname grafana hostn…

Springboot下使用Redis管道(pipeline)进行批量操作

之前有业务场景需要批量插入数据到Redis中&#xff0c;做的过程中也有一些感悟&#xff0c;因此记录下来&#xff0c;以防忘记。下面的内容会涉及到 分别使用for、管道处理批量操作&#xff0c;比较其所花费时间。 分别使用RedisCallback、SessionCallback进行Redis pipeline …

【BES2500x系列 -- RTX5操作系统】深入探索CMSIS-RTOS RTX -- 同步与通信篇 -- 消息队列和邮箱处理 --(四)

&#x1f48c; 所属专栏&#xff1a;【BES2500x系列】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f49…

【Node-RED 4.0.2】4.0版本新增特性(官方版)

二、重要功能 *1.时间戳格式改进 过去&#xff0c;node-red 只提供了 最原始的 timestamp 的格式&#xff08;1970-01-01 ~ now&#xff09; 但是现在&#xff0c;额外增加了 2 种格式&#xff1a; ISO 8601 -A COMMON FORMAT&#xff08;YYYY-MM-DDTHH:mm:ss:sssZ&#xff…

Linux环境安装配置nginx服务流程

Linux环境的Centos、麒麟、统信操作系统安装配置nginx服务流程操作&#xff1a; 1、官网下载 下载地址 或者通过命令下载 wget http://nginx.org/download/nginx-1.20.2.tar.gz 2、上传到指定的服务器并解压 tar -zxvf nginx-1.20.1.tar.gzcd nginx-1.20.1 3、编译并安装到…

阿里Nacos下载、安装(保姆篇)

文章目录 Nacos下载版本选择Nacos安装Windows常见问题解决 更多相关内容可查看 Nacos下载 Nacos官方下载地址&#xff1a;https://github.com/alibaba/nacos/releases 码云拉取&#xff08;如果国外较慢或者拉取超时可以试一下国内地址&#xff09; //国外 git clone https:…

[数据集][目标检测]桥梁检测数据集VOC+YOLO格式1116张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1116 标注数量(xml文件个数)&#xff1a;1116 标注数量(txt文件个数)&#xff1a;1116 标注…

【RabbitMQ实战】Springboot 整合RabbitMQ组件,多种编码示例,带你实践 看完这一篇就够了

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、对RabbitMQ管理界面深入了解1、在这个界面里面我们可以做些什么&#xff1f; 二、编码练习&#xff08;1&#xff09;使用direct exchange(直连型交换机)&a…

snowflake 不再是个数据仓库公司了

标题先上结论&#xff0c;为啥这么认为&#xff0c;且听接下来道来。 snowflake 非常成功&#xff0c;开创了云数仓先河&#xff0c;至今在数仓架构上也是相对比较先进的&#xff0c;国内一堆模仿的公司&#xff0c;传统上我们会认为 snowflake 肯定是一家数据仓库公司。不过最…

3D Gaussian Splatting代码中的forward和backward两个文件代码解读

3dgs代码前向传播部分 先来讨论一下glm&#xff0c;因为定义变量的时候用到了这个。 glm的解释 glm 是指 OpenGL Mathematics&#xff0c;这是一个针对图形编程的数学库。它的全称是 OpenGL Mathematics (GLM)&#xff0c;主要用于 OpenGL 的开发。这个库是基于 C 的模板库&…

什么是CC攻击,如何防止网站被CC攻击的方法

前言 “CC攻击的原理就是攻击者控制某些主机不停地发大量数据包给对方服务器造成服务器资源耗尽&#xff0c;一直到宕机崩溃。” 什么是CC攻击&#xff1f; CC攻击前身是一个名为Fatboy的攻击程序&#xff0c;而之所以后来人们会称之为CC&#xff0c;也叫HTTP-FLOOD&#xff…

【AI提升】如何使用大模型:本机离线和FastAPI服务调用

大模型本身提供的功能&#xff0c;类似于windows中的一个exe小工具&#xff0c;我们可以本机离线调用然后完成具体的功能&#xff0c;但是别的机器需要访问这个exe是不可行的。常见的做法就是用web容器封装起来&#xff0c;提供一个http接口&#xff0c;然后接口在后端调用这个…

lodash.js 工具库

lodash 是什么? Lodash是一个流行的JavaScript实用工具库,提供了许多高效、高兼容性的工具函数,能够方便地处理集合、字符串、数值、函数等多种数据类型,大大提高工作效率。 lodash官网 文档参见:Lodash Documentation lodash 在Vue中怎么使用? 1、首先安装 lodash np…

JDK动态代理-AOP编程

AOPTest.java&#xff0c;相当于main函数&#xff0c;经过代理工厂出来的Hello类对象就不一样了&#xff0c;这是Proxy.newProxyInstance返回的对象&#xff0c;会hello.addUser会替换为invoke函数&#xff0c;比如这里的hello.addUser("sun", "13434");会…

Python 作业题1 (猜数字)

题目 你要根据线索猜出一个三位数。游戏会根据你的猜测给出以下提示之一&#xff1a;如果你猜对一位数字但数字位置不对&#xff0c;则会提示“Pico”&#xff1b;如果你同时猜对了一位数字及其位置&#xff0c;则会提示“Fermi”&#xff1b;如果你猜测的数字及其位置都不对&…