【Cpp】类和对象#拷贝构造 赋值重载

标题:【Cpp】类和对象#拷贝构造 赋值重载

@水墨不写bug


目录

(一)拷贝构造

(二)赋值重载

(三)浅拷贝与深拷贝


正文开始:

(一)拷贝构造

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

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

#include<string>
using namespace std;
class Person
{
public:Person(char* name, int age = 0){_name = (char*)malloc(strlen(name)+1);_name = name;_age = age;}Person(Person& p)//拷贝构造必须是类对象的引用,否则会引发无穷递归{_name = (char*)malloc(strlen(p._name) + 1);_name = p._name;_age = p._age;}
private:char* _name;int _age;
};
int main()
{Person p1((char*)"zhangsan",35);Person p2(p1);return 0;
}


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


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


4. 编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,还需要自己显式实现吗?

        对于编译器自己生成的拷贝构造,是浅拷贝,只能完成对内置类型的拷贝,因为内置类型的本质就是一个值,或者说就是几个直接携带信息的数据。

        但是对于自定义类型,其本身指向的地址才是有效的数据,它间接指向有效的数据,对它本身进行浅拷贝没有实际意义。

        由于编译器自动生成的拷贝构造会只完成浅拷贝所以这时候就需要自己手动显示实现自定义类型的深拷贝。


5. 拷贝构造函数典型调用场景:
        使用已存在对象创建新对象
        函数参数类型为类 类型对象(也就是普遍的以类对象传参的情况)
        函数返回值类型为类类型对象

实例:

class Person
{
public:Person(char* name, int age = 0){_name = (char*)malloc(strlen(name)+1);_name = name;_age = age;}Person(Person& p)//函数参数类型为类 类型对象(也就是普遍的以类对象传参的情况){_name = (char*)malloc(strlen(p._name) + 1);_name = p._name;_age = p._age;}Person& Modefy()//修改人的信息,返回Person这个修改后的类对象{}private:char* _name;int _age;
};
int main()
{Person p1((char*)"zhangsan",35);Person p2(p1);//使用已存在对象创建新对象return 0;
}

        为了提高程序效率,一般对象传参时,尽量使用引用类型,返回时根据实际场景,能用引用尽量使用引用。

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

(二)赋值重载

         C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

        函数名字为:关键字 operator(后面接需要重载的运算符符号)


        函数原型:返回值类型   operator操作符(参数列表)

实例:

Date& operator==(Date& d1)
{//...
}

注意
        不能通过连接其他符号来创建新的操作符:比如operator@ (不能创造操作符)
        重载操作符必须有一个类类型参数 (对于内置类型的操作符重载没有意义,因此只能对自定义类型的操作符重载)
        用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
        作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this


        . *(点星运算符,少用)/    ::(域作用限定符)/    sizeof(计算类型大小操作符)   /   ?:(三目操作符)    注意以上5个运算符不能重载。

1. 赋值运算符重载格式


        参数类型:const T&,传递引用可以提高传参效率(同时防止对象被修改)
        返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
        检测是否自己给自己赋值
        返回*this :要复合连续赋值的含义


2. 赋值运算符只能重载成类的成员函数,不能重载成全局函数


        原因:赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,故赋值运算符重载只能是类的成员函数。


3. 用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。

        注意:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值。


4.既然编译器生成的默认赋值运算符重载函数已经可以完成字节序的值拷贝了,还需要自己实现吗?

        类似的,内置类型自己本身就直接携带信息,可以直接拷贝;但是自定义类型的直接浅拷贝是没有意义的;所以对于自定义类型,我们需要自己手动显示实现赋值重载,内置类型则不需要。

      注意:如果类中未涉及到资源管理,赋值运算符是否实现都可以;一旦涉及到资源管理则必须要实现。

(三)浅拷贝与深拷贝

        浅拷贝和深拷贝是两种不同的拷贝方式,用于在编程中复制数据。

        浅拷贝是创建一个新的对象,新对象的内容与原对象相同,但是新对象中的引用类型的成员仍然指向原对象中的引用类型对象。换句话说,浅拷贝只是复制了对象的引用而已当原对象中的引用类型成员发生变化时,新对象中的引用类型成员也会随之变化。

        深拷贝是创建一个全新的对象,将原对象的所有成员(包括值类型和引用类型)逐一复制到新对象中。换句话说,深拷贝会复制对象中的引用类型,并创建一个新的引用类型对象。当原对象中的引用类型成员发生变化时,新对象中的引用类型成员不会随之变化。

        浅拷贝和深拷贝的区别在于对于引用类型成员的处理方式。浅拷贝只复制引用,而深拷贝会创建新的引用类型对象。

举一个例子:

        创建一个栈的对象stack_1;

        拷贝构造一个stack_2;

        如果使用的是编译器默认生成的浅拷贝方式,那么对 stack_2的操作本质上也就是对stack_1的操作,因为栈的底层是一个动态开辟的堆区数组,创建stack_2时因为浅拷贝只是拷贝了栈区上stack_1的指向堆的一个指针。因而两个栈指向的同一块堆上的数组。

        深拷贝则是在堆上重新开辟了一个数组,并把stack_1的值赋给stack_2。



完~

未经作者同意禁止转载 

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

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

相关文章

上位机开发PyQt(五)【Qt Designer】

PyQt5提供了一个可视化图形工具Qt Designer&#xff0c;文件名为designer.exe。如果在电脑上找不到&#xff0c;可以用如下命令进行安装&#xff1a; pip install PyQt5-tools 安装完毕后&#xff0c;可在如下目录找到此工具软件&#xff1a; %LOCALAPPDATA%\Programs\Python\…

Excel 批量获取sheet页名称,并创建超链接指向对应sheet页

参考资料 用GET.WORKBOOK函数实现excel批量生成带超链接目录且自动更新 目录 一. 需求二. 名称管理器 → 自定义获取sheet页名称函数三. 配合Index函数&#xff0c;获取所有的sheet页名称四. 添加超链接&#xff0c;指向对应的sheet页 一. 需求 ⏹有如下Excel表&#xff0c;需…

EPAI手绘建模APP资源管理和模型编辑器2

g) 矩形 图 26模型编辑器-矩形 i. 修改矩形的中心位置。 ii. 修改矩形的长度和宽度。 h) 正多边形 图 27模型编辑器-内接正多边形 图 28模型编辑器-外切正多边形 i. 修改正多边形的中心位置。 ii. 修改正多边形中心距离端点的长度。 iii. 修改正多边形的阶数。阶数为3&…

Day30:热帖排行、生成长图、将文件上传到云服务器、优化热门帖子列表、压力测试

热帖排行 不同的算分方式&#xff1a; 只存变化的帖子到redis中&#xff0c;每五分钟算一次分&#xff0c;定时任务 存redis 构建redis键 //统计帖子分数 //key:post:score -> value:postId public static String getPostScoreKey() {return PREFIX_POST SPLIT "…

练习题(2024/5/5)

1左叶子之和 给定二叉树的根节点 root &#xff0c;返回所有左叶子之和。 示例 1&#xff1a; 输入: root [3,9,20,null,null,15,7] 输出: 24 解释: 在这个二叉树中&#xff0c;有两个左叶子&#xff0c;分别是 9 和 15&#xff0c;所以返回 24示例 2: 输入: root [1] 输…

LeetCode 131 —— 分割回文串

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 首先&#xff0c;按照 LeetCode 5——最长回文子串 中的思路&#xff0c;我们先求出 d p dp dp&#xff0c;这样我们就知道了所有的子串是否是回文子串。 然后&#xff0c;我们进行一个 dfs 搜索&#xff0c;起…

5月4(信息差)

&#x1f384; HDMI ARC国产双精度浮点dsp杜比数码7.1声道解码AC3/dts/AAC环绕声光纤、同轴、USB输入解码板KC33C &#x1f30d; 国铁集团回应高铁票价将上涨 https://finance.eastmoney.com/a/202405043066422773.html ✨ 源代码管理平台GitLab发布人工智能编程助手DuoCha…

AI大模型探索之路-训练篇11:大语言模型Transformer库-Model组件实践

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

QT5带UI的常用控件

目录 新建工程&#xff0c;Qmainwindow带UI UI设计器 常用控件区 Buttons 按钮 containers 容器 控件属性区域 对象监视区 布局工具区 信号与槽区 简单例子1 放置一个按钮控件&#xff0c;改文本为发送&#xff0c;该按键为Button1&#xff1b; 按钮关联信号和…

Redisson 分布式锁和同步器

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 redisson 是基于redis的扩展库,使得redis除了应用于缓存以外,还能做队列…

golang学习笔记(内存模型和分配机制)

操作系统的存储管理 虚拟内存管理 虚拟内存是一种内存管理技术&#xff0c;它允许操作系统为每个进程提供一个比实际物理内存更大的地址空间。这个地址空间被称为虚拟地址空间&#xff0c;而实际的物理内存则被称为物理地址空间。使用虚拟内存有以下几点好处&#xff1a; 内…

【机器学习-21】集成学习---Bagging之随机森林(RF)

【机器学习】集成学习---Bagging之随机森林&#xff08;RF&#xff09; 一、引言1. 简要介绍集成学习的概念及其在机器学习领域的重要性。2. 引出随机森林作为Bagging算法的一个典型应用。 二、随机森林原理1. Bagging算法的基本思想2. 随机森林的构造3. 随机森林的工作机制 三…

JVM的垃圾回收机制(GC机制)

在Java代码运行的过程中&#xff0c;JVM发现 某些资源不需要再使用的时候&#xff0c;就会自动把资源所占的内存给回收掉&#xff0c;就不需要程序员自行操作了。“自动回收资源”就是JVM的“垃圾回收机制”&#xff0c;“垃圾回收机制”也称"GC机制"。 对于Java代码…

【论文笔记】Training language models to follow instructions with human feedback A部分

Training language models to follow instructions with human feedback A 部分 回顾一下第一代 GPT-1 &#xff1a; 设计思路是 “海量无标记文本进行无监督预训练少量有标签文本有监督微调” 范式&#xff1b;模型架构是基于 Transformer 的叠加解码器&#xff08;掩码自注意…

OceanBase开发者大会实录-杨传辉:携手开发者打造一体化数据库

本文来自2024 OceanBase开发者大会&#xff0c;OceanBase CTO 杨传辉的演讲实录—《携手开发者打造一体化数据库》。完整视频回看&#xff0c;请点击这里&#xff1e;> 各位 OceanBase 的开发者&#xff0c;大家上午好&#xff01;今天非常高兴能够在上海与大家再次相聚&…

半监督节点分类:标签传播和消息传递

基础概念回顾 传统图机器学习的特征工程——节点层面&#xff0c;连接层面&#xff0c;全图层面 节点层面&#xff1a;信用卡欺诈 连接层面&#xff1a;推荐可能认识的人 全图层面&#xff1a;预测分子结构 半监督节点分类 半监督节点分类&#xff1a;用已知标签节点预测未…

路由器的构成

一、路由器简介 路由器是互联网中的关键设备&#xff1a; 连接不同的网络路由器是多个输入端口和多个输出端口的专用计算机&#xff0c;其任务是转发分组&#xff08;转发给下一跳路由器&#xff09;下一跳路由器也按照这种方法处理分组&#xff0c;直到该分组到达终点为止 …

Gone框架介绍3 - 使用gone命令,自动生成Priest函数

文章目录 1. 安装辅助工具: gone2. 创建一个名为gen-code的新项目3. 创建Goner4. 使用辅助工具5. 添加main函数 我在两年前实现了一个Golang的依赖注入框架&#xff0c;并且集成了gin、xorm、redis、cron、消息中间件等功能&#xff0c;自己觉得还挺好用的&#xff1b;之前一直…

js api part3

环境对象 环境对象&#xff1a; 指的是函数内部特殊的 变量 this &#xff0c; 它代表着当前函数运行时所处的环境 作用&#xff1a; 弄清楚this的指向&#xff0c;可以让我们代码更简洁 函数的调用方式不同&#xff0c;this 指代的对象也不同 【谁调用&#xff0c; this 就是…

中科院突破:TalkingGaussian技术实现3D人脸动态无失真,高效同步嘴唇运动!

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享&#xff0c;与你一起了解前沿深度学习信息&#xff01; 引言&#xff1a;探索高质量3D对话头像的新方法 在数字媒体和虚拟互动领域&#xff0c;高质量的3D对话头像技术正变得日益重要。这种技术能够在虚拟现实、电影…