C++重新认知:拷贝构造函数

一、什么是拷贝构造函数

对于简单变量来说,可以轻松完成拷贝。

int a = 10;
int b = a;

但是对于复杂的类对象来说,不仅存在变量成员,也存在各种函数等。因此相同类型的类对象是通过拷贝构造函数来完成复制过程的。

#include<iostream>using namespace std;class String
{
private:char* m_buffer;unsigned int m_size;
public:String(const char* string){m_size = strlen(string);m_buffer = new char[m_size + 1];memcpy(m_buffer, string, m_size);m_buffer[m_size] = 0;}~String(){delete[] m_buffer;}friend ostream& operator <<(ostream& stream, const String& string);
};
ostream& operator <<(ostream& stream,const String& string)
{stream << string.m_buffer;return stream;
}
int main()
{String a = "A";String b = a;//这里执行拷贝构造函数cout << a << endl;cout << b << endl;getchar();return 0;
}

在这里插入图片描述
可以看到成功拷贝了我们自己设计的String类(这里拷贝指的是默认拷贝构造函数即也是浅拷贝),当然这段代码是存在问题的
在这里插入图片描述
我们可以看到两块指向m_buffer内存地址相同,所以会出现多次析构的情况(即a对象析构完了,将m_buffer释放掉后,因为b对象指向的也是m_buffer区域又要释放一次已经释放掉的),这也是浅拷贝,下面会详细讲解浅拷贝和深拷贝。

二、拷贝构造函数的格式

拷贝构造函数的格式

类名(const 变量类型& other)
{
.......
}

要注意变量一定是本类型的可引用变量

三、拷贝构造函数的调用时机

1. 对象以值传递的方式传入函数参数

在这里插入图片描述

2.对象以值传递的方式从函数返回

在这里插入图片描述

3.对象需要通过另一个对象进行初始化

Test a(0,1);
Test b(a);
Test c = a;

四、浅拷贝和深拷贝

1.浅拷贝(上面样例中有涉及到这里就不在详细讲)

2.深拷贝

为了解决浅拷贝导致拷贝的对象指向内存与原被拷贝对象一致,导致析构两次的问题,我们需要手动提供另一种拷贝构造函数的方式————深拷贝。

#include<iostream>using namespace std;class String
{
private:char* m_buffer;unsigned int m_size;
public:String(const char* string){m_size = strlen(string);m_buffer = new char[m_size + 1];memcpy(m_buffer, string, m_size + 1);m_buffer[m_size] = 0;}String(const String& other):m_size(other.m_size){m_buffer = new char[m_size + 1];memcpy(m_buffer, other.m_buffer, m_size + 1);}~String(){delete[] m_buffer;//防止内存泄露}char& operator[](unsigned int index){return m_buffer[index];}friend ostream& operator <<(ostream& stream, const String& string);
};
ostream& operator <<(ostream& stream,const String& string)
{stream << string.m_buffer;return stream;
}
int main()
{String a = "A";String b = a;//这里执行拷贝构造函数b[0] = 'B';cout << a << endl;cout << b << endl;getchar();return 0;
}

深拷贝函数代码

String(const String& other):m_size(other.m_size){m_buffer = new char[m_size + 1];memcpy(m_buffer, other.m_buffer, m_size + 1);}

在这里插入图片描述
在这里插入图片描述
可以看到两个对象的m_buffer地址不再一样。即拷贝的对象又重新分配了一份自己的m_buffer地址。

但是当我们比如有一些函数,我们本来就不需要让他拷贝(例如输出之类的函数),因为拷贝他们没有任何意义。
这里举一个例子:
在这里插入图片描述
在这里插入图片描述
这里执行后的结果:

在这里插入图片描述
可以看到,跟我们上面二中对象以值传递的方式传入函数参数说的一样它会调用拷贝函数,但是这是非常没有效率的,因为我们仅仅只是希望它输出,而非拷贝一份在输出,这样是没有任何意义的。
我们该如何做呢?很简单
我们只需要传引用(&)就可以
在这里插入图片描述
在这里插入图片描述
这样就可以防止无效拷贝导致效率降低的问题了。

重要:总是通过const引用去传递对象来减少无效的拷贝来增加效率

以上就是拷贝构造函数的所有内容了如果读者觉得本文章对你有收益,还请关注,点赞!

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

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

相关文章

基于 TensorFlow.js 构建垃圾评论检测系统

基于 TensorFlow.js 构建垃圾评论检测系统。 准备工作 在过去的十年中,Web 应用变得越来越具有社交性和互动性,而即使是在中等热门的网站上,也有数万人可能实时对多媒体、评论等的支持。这也让垃圾内容发布者有机会滥用此类系统,将不太令人满意的内容与其他人撰写的文章、视…

小程序必看系列!什么是抖音小程序?抖音小程序怎么制作?

随着移动互联网的飞速发展&#xff0c;抖音已经成为了一个广受欢迎的短视频平台。在这个平台上&#xff0c;用户可以分享自己的生活点滴、表达自己的观点&#xff0c;甚至还能通过小程序来丰富自己的社交体验。那么&#xff0c;如何制作抖音小程序呢&#xff1f; 一、抖音小程…

5288 SDH/PDH数字传输分析仪

5288 SDH/PDH数字传输分析仪 数字通信测量仪器 5288 SDH/PDH数字传输分析仪为高性能手持式数字传输分析仪&#xff0c;符合ITU-T SDH/PDH技术规范和我国光同步传输网技术体制的规定,支持2.048、34.368、139.264Mb/s及155.520Mb/s传输速率的测试。可进行SDH/PDH传输设备和网络的…

云畅科技技术中心被认定为湖南省省级企业技术中心

近日&#xff0c;湖南省工业和信息化厅公布《2023年第二批湖南省省级企业技术中心(第29批)》&#xff0c;云畅科技技术中心作为研发设计型代表入选。 省级企业技术中心是强化企业技术创新主体地位&#xff0c;增强企业自主创新能力&#xff0c;推动工业企业高质量发展的一个重要…

SQL-分组查询

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现错误&am…

turnjs实现翻书效果

需求&#xff1a;要做一个效果&#xff0c;类似于阅读器上的翻书效果。 咱们要实现这个需求就需要使用turnjs这个插件&#xff0c;他的官网是turnjs官网。 进入官网后可以点击 这个按钮去下载官网的demo。 这个插件依赖于jQuery&#xff0c;所以你的先安装jQuery. npm insta…

Unity URP下阴影锯齿

1.概述 在Unity开发的URP项目中出现阴影有明显锯齿。如下图所示&#xff1a; 并且在主光源的Shadow Type已经是Soft Shadows模式了。 2.URP Asset 阴影出现锯齿说明阴影质量不高&#xff0c;所以要先找到URP Asset文件进行阴影质量参数的设置。 1.打开PlayerSetting找到Graph…

代码签名证书怎么选择?软件开发者必看

随着互联网的高速发展&#xff0c;各种购物、资讯、社交类软件高速增长。而对于软件开发者来说&#xff0c;选择合适的代码签名证书来为软件进行数字签名、确保软件程序代码的完整性和软件的可信任性是很有必要的。但市场上有多种品牌、多种类型的代码签名证书可以选择&#xf…

03.阿里Java开发手册——OOP规约

【强制】避免通过一个类的对象引用访问此类的静态变量或静态方法&#xff0c;无谓增加编译器解析成本&#xff0c;直接用类名来访问即可。 【强制】所有的覆写方法&#xff0c;必须加Override 注解。 说明&#xff1a;getObject()与 get0bject()的问题。一个是字母的 O&#x…

vue前端开发自学,插槽练习,同时渲染父子组件的数据信息

vue前端开发自学,插槽练习,同时渲染父子组件的数据信息&#xff01; 如果想在slot插槽出口里面&#xff0c;同时渲染出来&#xff0c;来自父组件的数据&#xff0c;和子组件自身的数据呢。又有点绕口了。vue官方给的解决办法是。需要借助于&#xff0c;父组件的自定义属性。 …

第二百五十九回

文章目录 知识回顾示例代码经验总结 我们在上一章回中介绍了MethodChannel的使用方法&#xff0c;本章回中将介绍EventChannel的使用方法.闲话休提&#xff0c;让我们一起Talk Flutter吧。 知识回顾 我们在前面章回中介绍了通道的概念和作用&#xff0c;并且提到了通道有不同的…

本地部署Canal笔记-实现MySQL与ElasticSearch7数据同步

背景 本地搭建canal实现mysql数据到es的简单的数据同步&#xff0c;仅供学习参考 建议首先熟悉一下canal同步方式&#xff1a;https://github.com/alibaba/canal/wiki 前提条件 本地搭建MySQL数据库本地搭建ElasticSearch本地搭建canal-server本地搭建canal-adapter 操作步骤…

24-1-9 bilibilic++音视频

下午两点面试&#xff0c;面试官迟到了一会&#xff0c;面试官人很好&#xff0c;整体面试经历很不错&#xff0c;但是我人太紧张了&#xff0c;基础知识掌握的深度不够&#xff0c;没有深挖&#xff0c; 是做音视频的底层相关的&#xff0c; 实习要求只要每天打卡够九个小时就…

禁用code server docker容器中的工作区信任提示

VSCode 添加受限模式&#xff0c;主要是防止自动运行代码的&#xff0c;比如在vscode配置的task和launch参数是可以运行自定义代码的。如果用VScode打开未知的工程文件就有可能直接运行恶意代码。 但是当我们的实验基础模板文件可控的情况下&#xff0c;要想禁用code server do…

vue前端开发自学,组件的嵌套关系demo

vue前端开发自学,组件的嵌套关系demo!今天开始分享的&#xff0c;前端开发经常用到的&#xff0c;组件的嵌套关系案例代码。下面先给大家看看&#xff0c;代码执行效果。 如图&#xff0c;这个是代码执行后&#xff0c;的效果布局&#xff01; 下面给大家贴出来源码。方便大家…

认识字面量

字面量&#xff1a;数据在程序中的书写格式 整数小数写法无变化 字符&#xff1a;在程序中必须使用单引号&#xff0c;有且只能有一个字符 字符串&#xff1a;程序中必须使用双引号&#xff0c;内容可有可无 布尔值&#xff1a;true、false 空值&#xff1a;null 示例和结…

功效产品如何做好营销?媒介盒子解答

功能性产品目前的营销痛点就在于宣传夸张导致用户信任度降低&#xff0c;尤其是健康类产品&#xff0c;作为消费者&#xff0c;对此类产品大多持观望态度&#xff0c;但媒介盒子作为提供品牌宣传服务的团队&#xff0c;想和大家聊聊&#xff1a;功能性产品除了在功能上进行宣传…

【Java】解决Servlet编程中出现的中文乱码问题

1、引言 前面两篇文章我们讲述了编写Servlet程序的基本步骤和修改一个Servlet程序 【Java】编写一个简单的Servlet程序​​​​​​ 【Java】SmartTomcat的配置及使用 上面两篇文章的示例代码都是使用的全英文&#xff0c;当我们编写中文&#xff0c;发现似乎出了一点点问题…

【100个 Unity实用技能】☀️ | UGUI中 判断屏幕中某个坐标点的位置是否在指定UI区域内

&#x1f3ac; 博客主页&#xff1a;https://xiaoy.blog.csdn.net &#x1f3a5; 本文由 呆呆敲代码的小Y 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;Unity系统学习专栏 &#x1f332; 游戏制作专栏推荐&#xff1a;游戏制作 &…

【一文搞懂JVM的内存屏障】

要命的问题&#xff1a; 什么是线程的安全性&#xff1f;怎么保证&#xff1f;jvm什么是的内存屏障&#xff1f;他有什么作用&#xff1f; **线程的安全性是指&#xff1a;**指在多线程环境下&#xff0c;多个线程同时访问同一资源时不会产生意外结果或导致数据出错的状态。其…