当前位置: 首页 > news >正文

【C++】类和对象(五):拷贝构造

大家好,我是苏貝,本篇博客带大家了解C++的拷贝构造函数,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
在这里插入图片描述


目录

  • a. 概念
  • b. 特性

a. 概念

在创建对象时,可否创建一个与已存在对象一样的新对象呢?

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

b. 特性

拷贝构造函数也是特殊的成员函数,其特征如下:

  1. 拷贝构造函数是构造函数的一个重载形式。
  2. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错, 因为可能会引发无穷递归调用。
    在这里插入图片描述

为什么拷贝构造函数的形参一定要是引用而不能用传值传参?
C++规定,自定义类型传值传参时,会调用该自定义类型的拷贝构造函数,用类Date举例

在这里插入图片描述

如果拷贝构造函数是传值传参

在这里插入图片描述

可以在拷贝构造函数内部写判断条件来跳出这个无穷递归吗?
不能,因为根本没有进到函数体里,只是在需要形参时,就进入下一个递归

注意不要将拷贝构造函数的内容写反,this指针是指向调用该函数的对象
在这里插入图片描述

如果类中的构造函数只有拷贝构造,会报错,因为定义对象时需要调用默认构造函数(自己写的无参构造,全缺省构造和编译器生成的构造)

在这里插入图片描述
在这里插入图片描述

为了解决这一问题,我们可以手动写无参/全缺省的构造函数,或者用语句让编译器强制生成一个无参的

在这里插入图片描述

  1. 若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝

用已经存在的a1拷贝构造a2,此处会调用A类的拷贝构造函数,但A类并没有显式定义拷贝构造函数,则编译器会给A类生成一个默认的拷贝构造函数

在这里插入图片描述

  1. 如果是编译器生成的拷贝构造函数,那么该函数对内置类型进行浅拷贝(值拷贝),对自定义类型调用它的拷贝构造

下图的Date类没有显示写拷贝构造函数,由编译器自动生成一个,它对内置类型进行值拷贝,对自定义类型_t调用它的拷贝构造

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,还需要自己显式实现吗? 当然像日期类这样的类是没必要的,可在有些情况下会出错,如下面的栈

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

运行崩溃,运行的时候出现这个错误,绝大多数都是未分配内存的原因,可以在申请空间的地方,初始化的地方多多检查。

我们来调试看看

在这里插入图片描述

我们在Stack类中没有写拷贝构造函数,因此编译器会自动生成一个。调试发现,在拷贝完成后(编译器生成的拷贝构造函数,将对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝),st2的指向数组的指针_array和st1的指向数组的指针_array的值一样,即它们指向同一块内存空间。当对象生命周期结束时,C++编译系统自动调用析构函数(注意:先定义的对象后调用析构函数)。
St2调用析构函数后,释放了数组空间,并将_array置为空。再St1调用析构函数,它的_array不为空,释放数组空间,但这块空间已被st2释放,两次释放报错

在这里插入图片描述

因此这时我们不能用编译器自动生成的拷贝构造,需要自己写

在这里插入图片描述
在这里插入图片描述

注意:类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请 时,则拷贝构造函数是一定要写的,否则就是浅拷贝。


好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️


http://www.mrgr.cn/news/61723.html

相关文章:

  • React核心思维模型(一)
  • Java-I/O框架06:常见字符编码、字符流抽象类
  • MATLAB车道检测与跟踪
  • net Attribute 特性 、 Property 属性
  • SpringBoot 解析@Value注解型解析注入时机以及原理
  • 面向对象进阶(下)(JAVA笔记第二十五期)
  • 深入浅出Python网络爬虫:从入门到实战(附爬虫实战代码)
  • mac ssh 连接 linux 服务器
  • YOLOv8模型改进 第十六讲 添加频率谱动态聚合模块FSDA 去除图像噪声
  • spring boot 3.x 整合Swagger3
  • 【传知代码】知识图谱推理(论文复现)
  • 利用大语言模型实现模拟版图自动化
  • 认知战认知作战:顺治帝迁都北京的认知作战分析与策略
  • 预告帖|在MATLAB/Simulink中调用C语言的几种方法
  • 查询windows或者linux上 支持的所有字体
  • Kubeadm搭建k8s
  • 直播带货视频素材网站推荐
  • 跟着小土堆学习pytorch(五)——dataloader
  • Java爬虫的京东“寻宝记”:揭秘商品类目信息
  • vue打包的dist文件,再使用eletron打包为exe
  • GitHub Copilot 转型采用多模型策略,支持 Claude 3.5 和 Gemini
  • Cesium中遇到 materialProperty.getType is not a function
  • 2024 FinTechathon 校园行:助力高校学生探索金融科技创新
  • PHP爬虫的奇幻之旅:如何用代码“偷窥”京东商品的SKU信息
  • 使用Python实现一个简单的HTTP服务器:返回当前时间
  • 【机器学习】音乐与AI的交响:机器学习在音乐产业中的应用