C++:拷贝构造函数

news/2024/7/27 7:41:33/文章来源:https://blog.csdn.net/pancodearea/article/details/136538404

1.概念

      在现实生活中,可能存在一个与你一样的自己,我们称之为双胞胎。那在创建对象的时候,可否创建一个与已存在对象一模一样的新对象呢?答案是可以的,这就要通过拷贝构造函数来实现了。

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

2.特征

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

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

     因为不是引用,是值调用,所以要创建临时对象来拷贝值,但这样无疑会造成无穷递归调用

3.若没有显式定义,编译器会生成默认的拷贝构造函数。默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝
class Time
{public:Time(){_hour = 1;_minute = 1;_second = 1;}Time(const Time& t){_hour = t._hour;_minute = t._minute;_second = t._second;cout << "Time::Time(const Time&)" << endl;}private:int _hour;int _minute;int _second;
};
class Date
{private:// 基本类型(内置类型)int _year = 1970;int _month = 1;int _day = 1;// 自定义类型Time _t;
};int main()
{Date d1;// 用已经存在的d1拷贝构造d2,此处会调用Date类的拷贝构造函数// 但Date类并没有显式定义拷贝构造函数,则编译器会给Date类生成一个默认的拷贝构
造函数Date d2(d1);return 0;
}

     在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的。 

4.编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,那么还需要我们显式实现吗?
typedef int DataType;
class Stack
{
public:Stack(size_t capacity = 10){_array = (DataType*)malloc(capacity * sizeof(DataType));if (nullptr == _array){perror("malloc申请空间失败");return;}_size = 0;_capacity = capacity;
}void Push(const DataType& data){// CheckCapacity();_array[_size] = data;_size++;}~Stack(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}
private:DataType *_array;size_t _size;size_t _capacity;
};
int main()
{Stack s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);Stack s2(s1);return 0;
}

      在这里程序会崩溃掉,为什么呢? 首先s1对象调用构造函数创建,在构造函数中,默认申请了10个元素的空间,然后里面存了4个元素1 2 3 4;

       然后s2对象使用s1拷贝构造,而Stack类中没有显式定义拷贝构造函数,则编译对象会给Stack类生成一份默认的拷贝构造函数,默认拷贝构造函数是按照值拷贝的,即将s1中内容原封不动的拷贝到s2中,连指针的值也拷贝了,因此s1和s2指向了同一块内存空间;

       当程序退出时,s2和s1要销毁,s2先销毁,s2销毁时调用析构函数,已经将0x11223344的空间释放了,但是s1并不知道,会将该空间再释放一次,一块内存空间多次释放,肯定会造成程序崩溃。

注意:类中如果没有涉及资源申请时,拷贝构造函数是否写都可以一旦涉及到资源申请时,拷贝构造函数是一定要写的,否则就是浅拷贝
5.拷贝构造函数典型调用场景:使用已存在对象创建新对象函数参数类型为类类型对象函数返回值类型为类类型对象
class Date
{
public:Date(int year, int minute, int day){cout << "Date(int,int,int):" << this << endl;}Date(const Date& d){cout << "Date(const Date& d):" << this << endl;}~Date(){cout << "~Date():" << this << endl;}
private:int _year;int _month;int _day;
};Date Test(Date d){Date temp(d);return temp;}
int main()
{Date d1(2022,1,13);Test(d1);return 0;
}

    该程序的执行情况如下: 

    第一步:调用构造函数创建d1;

    第二步:Test函数以值传递,传参时候使用拷贝构造函数创建d;

    第三步:调用拷贝构造函数创建temp;

    第四步:函数以值方式返回,返回时使用temp拷贝构造临时对象来返回

    最后就是销毁Test函数中的temp,d,返回时创建的临时对象,以及main函数的d1。

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

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

相关文章

MindOpt优化器: 浅谈版本0.x和1.x之间API的差异

Mindopt 是一个优化求解器&#xff0c;如果它有两个主要版本——0.xx和1.x.x&#xff08;最新版本1.1.1&#xff09;&#xff0c;它们代表着软件开发的两个不同阶段。版本1.0.0表示软件的一个大的里程碑&#xff0c;代表着软件第一个正式的“成熟”发布版本&#xff0c;而0.25是…

【SpringBoot】多环境切换的灵活配置

文章目录 profile 的使用激活 profile 的方式命令行启动idea 中配置配置文件中激活 开发中最灵活的多环境配置创建四个配置主配置文件其他几个环境配置使用方式 配置文件拆分总结 在日常的开发中&#xff0c;一般都会分好几种环境&#xff0c;比如通常的 开发环境&#xff1a;一…

NTFS Disk by Omi NTFS for mac v1.1.4中文版

NTFS Disk by Omi NTFS for Mac&#xff1a;NTFS文件系统的无缝桥梁 软件下载&#xff1a;NTFS Disk by Omi NTFS for mac v1.1.4中文版 &#x1f310; 跨平台访问&#xff0c;文件无阻 NTFS Disk by Omi NTFS for Mac 为您的Mac提供了对NTFS文件系统的无缝访问。无论您是在Win…

FPGA-VGA成像原理与时序

什么是VGA: VGA, Video Graphics Array。即视频图形阵列,具有分辨率高、显示速率快、颜色丰富等优点。VGA接口不但是CRT显示设备的标准接口,同样也是LCD液晶显示设备的标准接口,具有广泛的应用范围。在FGPA中,常广泛用于图像处理等领域。 VGA 显示器成像原理 在 VGA 标准刚兴…

戏说c第二十六篇: 测试完备性衡量(代码覆盖率)

前言 师弟&#xff1a;“师兄&#xff0c;我又被鄙视了。说我的系统太差&#xff0c;测试不过关。” 我&#xff1a;“怎么说&#xff1f;” 师弟&#xff1a;“每次发布版本给程夏&#xff0c;都被她发现一些bug&#xff0c;太丢人了。师兄&#xff0c;有什么方法来衡量测试的…

供应链思维导图

https://author.baidu.com/home?frombjh_article&app_id1733215801356691 1 供应链管理流程图 2. 进销存 功能

【李沐精读系列】GPT、GPT-2和GPT-3论文精读

论文&#xff1a; GPT&#xff1a;Improving Language Understanding by Generative Pre-Training GTP-2&#xff1a;Language Models are Unsupervised Multitask Learners GPT-3&#xff1a;Language Models are Few-Shot Learners 参考&#xff1a;GPT、GPT-2、GPT-3论文精读…

VBA_MF系列技术资料1-395

MF系列VBA技术资料1-395 为了让广大学员在VBA编程中有切实可行的思路及有效的提高自己的编程技巧&#xff0c;我参考大量的资料&#xff0c;并结合自己的经验总结了这份MF系列VBA技术综合资料&#xff0c;而且开放源码&#xff08;MF04除外&#xff09;&#xff0c;其中MF01-0…

《解密云计算:企业之选》

前言 在当今数字化时代,企业面临着巨大的数据处理压力和信息化需求,传统的IT架构已经无法满足日益增长的业务需求。在这样的背景下,越来越多的企业开始转向云计算,以实现灵活、高效和可扩展的IT资源管理和利用。 云计算 云计算是一种基于互联网的计算模式,它通过将数据、…

ElasticSearch之分片相关概念segment,merge,refresh等

写在前面 本文看下分片相关概念&#xff0c;segment&#xff0c;merge&#xff0c;refresh等。 1&#xff1a;segment&#xff0c;commit point&#xff0c;.del 一个倒排索引的文件称为segment&#xff0c;多个segment组合在一起就是lucene的index&#xff0c;也就是es的sh…

五种msvcp140.dll丢失的解决方法

《绝地求生》&#xff08;PUBG&#xff09;的玩家数量在不同时期有所变化&#xff1a; 最新的官方数据显示&#xff0c;截至2023年2月1日&#xff0c;PUBG全球玩家总数已经超过4亿&#xff0c;并且当时有月活跃玩家2.27亿和日活跃玩家8700万。 而在较早的一个时间点&#xff…

JS判断对象属性是否存在

一 、在JavaScript中&#xff0c;有几种方法可以判断对象属性是否存在&#xff1a; 使用in操作符&#xff1a; property in object 例如&#xff1a;name in obj&#xff0c;如果obj对象有name属性&#xff0c;返回true&#xff0c;否则返回false。 使用hasOwnProperty()方法&…

为什么说鸿蒙开发就业面广?人才遭“爆抢”的背后说明什么?

鸿蒙开发&#xff0c;作为华为推出的全新操作系统&#xff0c;自其诞生以来就备受关注。而鸿蒙开发就业面广&#xff0c;人才遭“爆抢”的现象&#xff0c;更是引发了业界的广泛讨论。那么&#xff0c;这一现象背后究竟隐藏着怎样的原因和深意呢&#xff1f; 首先&#xff0c;…

基于单片机的家庭防盗报警器设计

目 录 摘 要 II Abstract III 引 言 1 1 系统方案设计 4 1.1 方案论证 4 1.2 项目总体设计 5 2 项目硬件设计 7 2.1 单片机型号的选择 7 2.2 单片机的引脚说明 8 2.3 单片机的最小系统 9 2.3.1 时钟电路设计 9 2.3.2 复位电路设计 10 2.4 红外信号采集及其处理 11 2.5 蜂鸣器电…

C语言第三十五弹---文件操作(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 文件操作 1、为什么使用文件&#xff1f; 2、什么是文件&#xff1f; 2.1、程序文件 2.2、数据文件 2.3、文件名 3、二进制文件和文本文件 4、文件的打开和…

高校水电预付费系统有什么作用?

Hey小伙伴们&#xff0c;今天来聊聊咱们大学里的一个超级实用的设施——水电预付费系统&#xff01;你是不是还在为每个月的水电账单烦恼呢&#xff1f;别担心&#xff0c;这个系统就是你的生活小帮手&#xff01; 首先&#xff0c;想象一下这 样的场景&#xff1a;开学初&…

win11修改主机mac地址

很多时候&#xff0c;为了限制恶意的蹭流浪&#xff0c;除了分配固定的ip地址外&#xff0c;还限制mac地址。只有mac与ip一致&#xff0c;才能上网冲浪 网络适配器中修改 搜索“控制面板”打开 控制面板 > 网络和Internet > 网络和共享中心 >查看网络状态和任务>…

机器学习 | 四大常用机器学习Python库介绍

今天这篇我们介绍下Python中常用的机器学习库(机器学习、深度学习啥的&#xff0c;小编还是建议使用Python进行建模编写哈)&#xff0c;也算是本公号机器学习的第一篇推文&#xff0c;主要内容如下&#xff1a; 机器学习常用四大Python库 关于机器学习的我想说的话 所有完整代…

vue3的开发小技巧

「总之岁月漫长&#xff0c;然而值得等待。」 目录 父组件调用子组件函数如何访问全局api 父组件调用子组件函数 ref, defineExpose //父组件 代码 <child ref"ch">this.$refs.ch.fn();//子组件 函数抛出 const fn () > { }; defineExpose({ fn });如何…

【Leetcode每日一题】 前缀和 - 连续数组(难度⭐⭐)(30)

1. 题目解析 题目链接&#xff1a;525. 连续数组 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 核心在于计算题目所给数组是否存在连续子数组使得数组里头0和1的数量相同&#xff0c;存在返回连续子数组最长长度即可&#xff0c…