c++拷贝构造与赋值运算符重载

news2024/12/24 2:26:26

目录

目录:

        1:拷贝构造

        2:赋值运算符重载

        


              

        前言:在上一章我们已经学习过了,构造与析构这两个默认成员函数了,接下来让我们一起来学习另外两个重要的默认成员函数。

        首先让我们来讲一下默认成员函数这个概念,所谓的默认成员函数,就是只要是类,类成员中就必定会含有这6个默认成员函数,空类也含有这6个默认成员函数。接下来让我们一起来学习拷贝构造与赋值重载吧。 

1:拷贝构造

        概念:函数名与类名相同,只有一个形参,且该形参是对本类类型对象的引用(一般用const修饰),在用已存在的类类型对象创建新对象时编译器自动调用。

        拷贝构造的特点:

        1:拷贝构造其实是构造函数的一种重载方式。(形参为该类类型对象的引用)

        2:拷贝构造只有一个参数,且该参数必须为该类类型对象的引用,如果是该类类型(传值),那么会形成无限递归,编译器在编译的时候会报错。 

        3: 当我们在一个类中并没有写拷贝构造函数的时候,编译器会自动生成一个默认的拷贝构造函数,这个默认的拷贝构造会按照字节拷贝的方式来进行拷贝,这种方式又被称为值拷贝(浅拷贝)。

        4:拷贝构造对于内置类型的成员完成值拷贝,对于自定义类型的成员调用它的拷贝构造,一般自定义类型成员的拷贝构造需要写一个深拷贝构造函数。

        注意:当类中没有申请内存资源的时候我们拷贝构造可写可不写,但是当类中申请了内存资源的时候我们就一定要写拷贝构造,不然我们程序会崩溃掉。

        我们通过图来解释上面的语法。

        

        那么为啥在传值的时候会报错呢?我们来分析一下 

        

         而当我们将拷贝构造的形参设置为,该类类型对象的引用时,引用并不是实参的拷贝,引用是实参的别名,所以不会形成无限的拷贝构造,也不会出错,真正才是拷贝构造规定的语法。

                

 对于语法3

        

             我们已经将我们写的拷贝构造函数给注释掉了,可是为什么我们在用d2拷贝d1的时候,还是完成了拷贝呢?这里是因为我们不写拷贝构造的时候,编译器会自动生成一个拷贝构造来完成值拷贝(浅拷贝)的工作,这也是默认成员函数牛逼的地方。

            可是当编译器会自动生成默认的拷贝构造的时候为什么我们还要学习拷贝构造函数的写法呢?

        这是因为呀,这个类并没有向内存中申请资源所以可以不用写拷贝构造利用编译器的拷贝构造就能够完成相应的功能,而当我们的类向编译器申请了内存资源呢?那又会发生什么呢?

        因为编译器的值拷贝是从内存中按照字节序来进行拷贝的,所以当我们的对象调用析构函数的时候,会对同一块空间完成两次析构,那么就会有非法访问内存的现象,编译器就会运行崩溃。

        如下图的描述:

        

       所以我们可以这样认为,我们学习拷贝构造,是为了当我们类对象向内存中申请空间的时候,我们就需要自己来写拷贝构造,这个用来解决申请内存空间的拷贝构造又叫做深拷贝。

        比如说下面的一个例子,我们定义一个Stack类

        

        假设我们使用的是它默认的构造函数。

        

        这里的程序就终止了,因为我们出变量的生命周期会自动调用它析构函数,所以就导致了释放两次同样的内存空间导致程序崩溃,调用析构函数的顺序与构造变量的顺序相反,在这里应该先调用的是st1的析构,在st调用的时候指针则会访问异常。

        所以我们应该自己来写一个构造函数,使得拷贝的时候并不指向同一块空间。

        如下代码 这也就可以使我们释放的时候并不是释放同一块空间

        当成员变量开辟空间的时候,我们需要自己来写拷贝构造函数,来完成深拷贝。

        下面是几个拷贝构造常用的几个场景

        1:用一个已知对象去创建另外一个对象

        2:函数参数类型为类类型对象

        3:函数返回值为类类型对象

        到这里我们的拷贝构造就讲解完毕了,然我们进入下一个知识点的讲解

        2:赋值运算符重载函数

        在讲赋值运算符重载函数之前,我们得先学一下运算符重载这个知识点。

        我们知道对于我们的内置类型(int char double....)变量来说,他们能够使用运算符来直接进行+-*/...等操作,这些变量的操作编译器会自动来识别,而对于自定义类型来说编译器并不能直接翻译,因为自定义类型比较复杂所以编译器并不能够识别,这也就需要程序员自己实现。

        运算符重载:用来解决自定义类型对象使用运算符的问题。

       函数名为:operator 运算符  

      其实运算符重载与普通函数的差别,只是运算符重载具有特定的函数名,其他的与普通函数一样。我们用日期类来举例,运算符重载的定义。

        

        这就是一个日期类的运算符重载的定义,与普通函数并没有差别很大。

        我们在定义运算符重载的时候需要注意的有以下几点

        1:我们并不能用operator运算符来增加新的运算符,必须与我们内置类型相似的。

        2:运算符重载的一个参数必须是类类型的,因为运算符重载是用来解决自定义类型的使用运算符的问题。

        3:我们不能改变运算符的意思,比如说operator+,我们并不能改变原有+的含义。

        4:当运算符重载函数作为类成员函数的时候,函数的形参比操作数永远少1,因为我们会将左操作数当作this指针传进来 。

        5: .* :: sizeof  ?: .这5个操作数并不能形成运算符重载

        有了运算符重载这个知识,我们就可以来学习默认成员函数的赋值运算符重载函数了,

        其实赋值运算符重载函数,也就是operator= 这个函数名的实现。

        赋值运算符重载函数当我们不写的时候编译器会默认的生成一个值拷贝,赋值运算符对于成员向内存开辟了空间那么我们的赋值运算符就要写深拷贝,与拷贝构造类似需要自己开空间。

        当我们使用赋值运算符重载函数的时候必须在类中实现不能在类外,因为当我们在类外实现的时候,因为编译器会看到我们类中并没有显示的写赋值运算符重载函数,所以就会默认生成,导致会有两个赋值运算符重载函数,会有冲突。

        赋值运算符重载的规则

        1:返回值为const 类名&   

        2:参数也是 const 类名&   用引用来提高效率

        3:返会*this,*this是左边操作数如  j = i+=5;  这里i+=5返回的是i。

        4:检查自己是否给自己赋值(自己给自己赋值不会报错,但是这样没什么意义)

        

        关于前置++与后置++的区分   i++,++i

        我们知道++运算符的函数名应该为  operator++,那么我们该如何来区分 前置与后置呢?

       在这里我们可能需要利用函数重载的概念来区分,因为他们两的函数名相同,所以我们可以利用参数使得它们区分。

        c++规定,在参数中加了如:operator(int)有形参的就是后置++,未有形参的就是前置++

     

    

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

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

相关文章

[架构之路-245/创业之路-76]:目标系统 - 纵向分层 - 企业信息化的呈现形态:常见企业信息化软件系统 - 企业资源管理计划ERP

目录 前言: 一、企业信息化的结果:常见企业信息化软件 1.1 企业资源管理计划 1.1.1 什么是ERP:企业最常用的信息管理系统 1.1.2 ERP的演进过程 1.1.3 EPR模块 1.1.4 EPR五个层级 1.1.5 企业EPR业务总体流程图 1.1.6 什么类型的企业需…

微信小程序云开发如何优雅的实现模糊查询

微信官方自从推出微信小程序云开发之后,让小程序开发的门槛再次降低,你可以不需要掌握任何后端的语言和数据库,有一些js的基本功,就可以完成一个完整带前后端交互功能的小程序项目。今天我们介绍一个日常开发中非常常见的需求&…

转化率(CVR)是什么意思,怎么计算和提高转化率?

转化率指的是在一定时间范围内,企业在线上或线下从事某项营销推广(比如竞价广告)活动时,成功完成转化行为的次数占推广信息总点击次数的百分比率。它是产品营销推广中的一个重要数据指标,转化率越高,成本越…

【教3妹学编辑-算法题】H 指数 II

3妹:2哥早啊, 新的一周开始了,奥利给!!! 2哥 :3妹,今天起的很早嘛,精神也很饱满。 3妹:昨天睡的早,早睡早起好身体! 2哥:既然离时间还…

不定长顺序表2

接下来我们看怎么完成不定长顺序表的代码实现 这里先加一个头文件,名字叫dsqlist.h,存放不定长顺序表的函数定义与声明 然后建立一个名字叫dsqlist.cpp的源文件,跟其头文件配对成一对,(也可以叫别的名字不配对)&…

Java 中的 synchronized 同步锁

导致线程安全问题的根本原因在于,存在多个线程同时操作一个共享资源,要想解决这个问题,就需要保证对共享资源访问的独占性,因此人们在Java中提供了synchronized关键字,我们称之为同步锁,它可以保证在同一时…

力扣每日一题83:删除排序数组中的重复元素

题目描述: 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 示例 1: 输入:head [1,1,2] 输出:[1,2]示例 2: 输入:head [1,1,2…

Day14力扣打卡

打卡记录 H 指数(二分) 链接 以最大值 x 为分割点的正整数数轴上,满足: 少于等于 x 的数值必然满足条件;大于 x 的数值必然不满足。 采用右边界二分查找,寻找满足条件的最大 H 指数要求。 class Soluti…

shell脚本函数(极其粗糙版)

分界点:以下内容需要更改,正常放假更改 函数: 1、把整个命令序列按照格式写在一起 2、可以方便的重复使用的命令序列 使用函数可以避免代码重复 函数可以将大的工程分割为诺干小的功能模块,可以随时调用,代码的可读…

Windows一键添加命名前缀(文件)

温馨提示:使用前建议先进行测试和原文件备份,避免引起不必要的损失。 (一)需求描述 在上班摸鱼的我正准备打开手机刷会儿CSDN论坛,老板发给我一个压缩包并要求我给里面所有的文件的名称添加一个前缀”大项目_”。我本…

协同过滤音乐推荐系统

摘 要 信息化爆炸的时代,互联网技术的指数型的增长,信息化程度的不断普及,社会节奏在加快,每天都有大量的信息扑面而来,人们正处于数字信息化世界。数字化的互联网具有便捷性,传递快,效率高&am…

windows系统命令常用命令(常看当前路径等)

打开cmd命令行终端 按下 winr 快捷键,输入cmd,点击确定 查看当前路径 输入命令 chdir 查看目录下文件 输入命令 dir //查看当前目录下的文件,类似于linux下的ls cd /d e:\software //跳转到其他硬盘的其他文件夹,注意此处…

Linux权限的概念

文章目录 Linux权限管理01.文件访问者的分类(人)02.文件类型和访问权限(事物属性)03.文件权限值的表示方法04. 调整权限(文件访问权限的相关设置方法) ch系列是改变文件性质的指令;file指令可以…

CS224W2.3——传统基于特征的方法(图层级特征)

前两篇中我们讨论了节点层级的特征表示、边层级的特征表示: CS224W2.1——传统基于特征的方法(节点层级特征)CS224W2.2——传统基于特征的方法(边层级特征) 在这篇中,我们将重点从整个图中提取特征。换句话说,我们想要描述整个图结构的特征…

2.27每日一题(定积分求面积,旋转体体积)

1、遇到求面积、定积分的问题,先画图: (1)抛物线(可正可负,所以抛物线函数需要有 a 变量) (2)过两个点 2、定积分求面积有三种情况对应三条公式: &#xff0…

H5游戏源码分享-像素小鸟游戏(类似深海潜艇)

H5游戏源码分享-像素小鸟游戏&#xff08;类似深海潜艇&#xff09; 点击屏幕控制小鸟的飞行高度 整个小游戏就用JS完成 项目地址&#xff1a;https://download.csdn.net/download/Highning0007/88483228 <!DOCTYPE HTML> <html><head><meta http-equiv…

【C++】智能指针总结:auto_ptr、unique_ptr、share_ptr、weak_ptr(技术介绍 + 代码实现)

文章目录 0. 概述智能指针&#xff0c;智能在哪儿&#xff1f;RAII 的介绍四个智能指针的特点&#xff1a; 1. auto_ptr&#xff08;C98&#xff09;&#x1f40e;核心功能的简单实现 2. unique_ptr&#xff08;C11&#xff09;&#x1f40e;核心功能的简单实现 3. shared_ptr&…

LSMW应用

案 执行第二行 第六步直接跳过.

【2023MathorCup大数据竞赛】B题完整解答过程(思路+模型文档+代码+结果)

B题完整解答过程 写在最后技术文档&#xff08;部分&#xff09;问题分析假设符号说明1 基于自适应ARIMA-LR模型的需求量预测&#xff08;问题一第一小问&#xff09;1.1 ARIMA模型的建立1.2 LR模型的建立1.3 自适应混合ARIMA-LR模型的建立1.4 ARIMA模型的求解1.5 LR模型的求解…

图像分类任务ViT与CNN谁更胜一筹?DeepMind用实验证明

精华置顶 墙裂推荐&#xff01;小白如何1个月系统学习CV核心知识&#xff1a;链接 点击CV计算机视觉&#xff0c;关注更多CV干货 今天跟大家分享DeepMind发表的一篇技术报告&#xff0c;通过实验得出&#xff0c;CNN与ViT的架构之间虽然存在差异&#xff0c;但同等计算资源的预…