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

C++拷贝构造函数、赋值学习整理:

拷贝构造函数:

概念:

构造函数的第一个参数,是类本身的const引用(一般情况下没有其他参数,少数情况:其他参数必须有默认值!)称此类构造函数为拷贝构造函数

特征:

1:拷贝构造函数类名与函数值一致,没有返回值(与构造函数一致)

2:每个类都有拷贝构造函数,未定义时系统自动生成(可能产生错误)

      默认生成的拷贝构造函数:为每个成员分配内存空间、成员变量赋值(浅拷贝)

3:调用时只有一个实参,要求函数不能重载

      调用时仅对象作为实参,后面若有参数都为默认值,无法区分函数导致无法重载

4:第一个参数是类本身的const引用,存在其他有默认值的参数

//格式:
类名(const 类名&对象名);
class CPY
{public:CPY();//默认构造函数;CPY(const CPY& a);//拷贝构造函数...
};

拷贝构造函数的应用:

  • 用已经存在的对象初始化构造新的对象
  • 以类本身对象作为函数传递的实参,在非引用情况下(程序需要在函数中新创建一个相同的对象并复制值
  • 返回类型为非引用类型的函数返回一个对象
int main()
{CPY a{...};//构造CPY b(a);//拷贝构造CPY c=a;//拷贝构造MAX(a);//-> int MAX(const CPY a) //函数五引用对象传参:拷贝构造用于传参MAX(a,b)//->CPY MAX(const CPY& a,const CPY& b) return a;//有引用的传参不是拷贝构造函数//函数返回值使用拷贝构造函数}

注意:

拷贝构造函数是一种特殊的构造函数,其形参是本类对象的引用,且这个参数几乎总是const的引用。

拷贝构造函数作用即将一个已经存在的对象用于初始化构造新的对象,我们没有定义拷贝构造函数时,系统将自动构造拷贝构造函数:从给定对象中依次将每个非static成员拷贝到正在创建的新对象中。即分以下几种情况:

    1. 当该类的对象都是普通变量,默认拷贝构造函数可完成值的拷贝(浅拷贝),正确
    2. 当类的对象中出现指针、数组等变量,默认函数拷贝原来对象成员中的值到新创建的指针的值、数组的首地址(浅拷贝),错误
      1. 原因以下浅拷贝仅仅拷贝值,导致多处指针指向同一地址,当其中多对象生命周期结束时析构函数将指针同一地址多次释放导致系统崩溃
      2. 解决方法自定义拷贝构造函数使用深拷贝创建一新指针、数组(指向不同地址),再将其对象成员的指针、数组值赋值给新创建的对象成员(strcpy()或memcpy()),即得到指向不同地址的同值对象成员,满足拷贝构造函数、析构函数要求;
  1. 拷贝构造函数的参数采用引用方式,若是非引用:为调用拷贝构造函数需复制实参到形参,由复制的需要又得重新调用拷贝构造函数,产生无限循环;而引用即调用对象本身,无需复制

引例:

class Complex //复数类
{public:Complex(double r, double i);Complex(const Complex& c);Complex add(Complex c);//加法private:double real;    //实部double image;   //虚部
};
Complex::Complex(double r, double i) :real(r), image(i)
{cout << "构造函数,实部:"<<real<<",虚部:"<<image << endl;
}
Complex::Complex(const Complex & c)
{real = c.real;image = c.image;cout << "拷贝构造函数,实部:" << real << ",虚部:" << image << endl;
}Complex Complex::add(Complex c) 
{Complex y(real + c.real, image + c.image); //构造函数return y;//返回值为类对象,会调用拷贝构造函数
}
void f(Complex n) //参数是类对象,会调用拷贝构造函数
{cout << "f(Complex n)" << endl;
}
int main()
{Complex a(3, 4); //调用构造函数Complex b(6.5, 7.5);//调用构造函数Complex c(a); //拷贝构造函数Complex d = c;//拷贝构造函数,注意和下一节的赋值区分开f(b); //拷贝构造函数c = a.add(b); //拷贝构造函数return 0;
}

程序分析:

  • 调用构造函数,创建了两个复数类对象a和b

  • 用已知对象初始化另一个对象,系统调用拷贝构造函数

  • 利用c初始化对象d,这一句看似=赋值,其实还是调用拷贝构造函数,因为这里还是初始化过程。
  • Complex d=c 等同 Complex d(c) 等同 Complex d{c},

  • 将实参b传给形参n,因为形参是非引用的类对象,调用拷贝构造函数。

  • 首先实参b传递给非引用形参c会调用拷贝构造函数,接着在add函数中定义了一个复数类对象y(24行),系统会调用构造函数。
  • 最后,函数add的返回值是一个非引用对象,系统会创建一个临时对象,将局部对象y赋值给临时对象,这时也要调用拷贝构造函数。

赋值:

同类的对象之间可以互相赋值,即一个对象的值可以赋值给另一个对象。对象之间的赋值通过“=”进行。默认就是把一个对象所有非static数据成员的值依次赋值给另一个对象。

//格式
对象名1 = 对象名2;

说明:

(1)对象的赋值只对其中的数据成员赋值,不对成员函数赋值。

每个对象的数据成员占用独立的存储空间,不同对象的数据成员占有不同的存储空间,赋值的过程是将一个对象的数据成员在存储空间的值复制给另一个对象的数据成员的存储空间。

而不同对象的成员函数是同一个函数代码段不需要、也无法对它们赋值

(2)类的数据成员中不能包括动态分配的数据,否则在赋值时可能出现意想不到的严重后果,(不同指针指向同一地址后多次释放delete,崩溃)

如果类的数据成员有指针,则一定要实现如下函数

1、构造函数 (如果没有,会出现野指针)

2、拷贝构造函数(如果没有,会出现浅拷贝)

3、重载 = 符号 (如果没有,会出现浅拷贝)

2、析构函数(内存泄漏)

        delete动态对象则自动调用析构函数,不delete不调用析构函数

        而动态成员需系统调用析构函数delete

拷贝构造函数与赋值区分:拷贝构造定义初始化阶段,赋值在定义完成后进行。

运算符重载

在类中重新定义运算符,赋予运算符新的功能适应类的运算,如果某个运算符重载了,那么在使用该运算符时,系统会自动调用。

格式如下:

返回值类型 operator 运算符(参数);
//注意 operator关键字必须写//例如:operator +()//表示:重载+运算符operator *()//表示:重载*运算符。

其中,operator 是 C++的关键字,专门用于定义运算符重载函数

运算符重载是一种形式的C++多态,它使得对象操作更直观,本质上也是属于函数重载

 假设有一个Student类,并为它定义了一个operator +()成员函数,以重载+运算符,如果有Student的对象s1,s2,s3。便可以编写这样的代码。

s1 = s2+s3; //简化
s1 = s2.operator+(s3);//复杂写法

已使用的引例:

1. 这是因为C++已经对string类重载了“+”运算符加法:

        string s1="abc";string ;s2="xyz"; s1+s2;

2. C++对“<<”和“>>”进行了重载,用户在不同的场景下使用它们,作用是不同的。

对于位运算而言:“<<”运算符是左移运算符,“>>”运算符是右移运算符

        “<<”运算符在输出操作中与流对象cout配合使用,是流插入运算符

        “>>”运算符在输入操作中与流对象cin配合使用,是流提取运算符

注意:运算符重载的赋值函数,要添加以下代码:避免同对象赋值判断

if(this==&s)
return;
// s 是实参地址
//防止同一地址相互赋值,先delete释放地址导致数据丢失

相关文章:

C++拷贝构造函数、赋值学习整理:

拷贝构造函数&#xff1a; 概念&#xff1a; 构造函数的第一个参数&#xff0c;是类本身的const引用&#xff08;一般情况下没有其他参数&#xff0c;少数情况&#xff1a;其他参数必须有默认值&#xff01;&#xff09;称此类构造函数为拷贝构造函数 特征&#xff1a; 1&am…...

[亲测源码]ps软件网页版在线使用 PS网站程序源码 photoshop网页版源码 网页版的ps软件源码

在线PS作图修图网页版PHP网站源码&#xff0c;PHP在线照片图片处理PS网站程序源码photoshop网页版。 有很多朋友们都是在用PS作图的&#xff0c;众所周知在使用和学习PS时是需要下载软件的&#xff0c;Photoshop软件对电脑配置也是有一定要求的&#xff0c;今天就为大家带来一…...

前端大厂面试题探索编辑部——第二期

目录 题目 单选题1 题解 关于TCP 关于UDP 单选题2 题解 A选项的HTTP是否是无状态协议 B选项的HTTP支持的方法 C选项的关于HTTP的状态码 D选项HTTP协议的传输格式 题目 单选题1 1.以下哪个描述是关于 TCP 和 UDP 的区别&#xff08;&#xff09; A. TCP 是无连接的…...

yaml学习笔记

文章目录 yaml语言学习yaml 简介yaml 和json 区别基本语法数据类型YAML 对象YAML 数组锚点和引用纯量 参考文档 yaml语言学习 最近发现在学习k8s中各种配置文件 都是使用的yaml 这种格式, 包括 docker-compose.yaml 也都是用这个格式配置部署项目信息,我就了解了一下这个语法就…...

深度强化学习(王树森)笔记04

深度强化学习&#xff08;DRL&#xff09; 本文是学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。本文在ChatGPT辅助下完成。 参考链接 Deep Reinforcement Learning官方链接&#xff1a;https://github.com/wangshusen/DRL 源代码链接&#xff1a;https://github.c…...

openssl3.2/test/certs - 074 - CT entry

文章目录 openssl3.2/test/certs - 074 - CT entry概述笔记setup074.shsetup074_sc1.shsetup074_sc2.shsetup074_sc3.shEND openssl3.2/test/certs - 074 - CT entry 概述 openssl3.2 - 官方demo学习 - test - certs 笔记 setup074.sh #! /bin/bash# \file setup074.sh# o…...

Angular组件(一) 分割面板ShrinkSplitter

Angular组件(一) 分割面板ShrinkSplitter 前言 分割面板在日常开发中经常使用&#xff0c;可将一片区域&#xff0c;分割为可以拖拽整宽度或高度的两部分区域。模仿iview的分割面板组件&#xff0c;用angular实现该功能&#xff0c;支持拖拽和[(ngModel)]双向绑定的方式控制区…...

抖音详情API:视频内容获取与解析技巧

一、引言 抖音是一款广受欢迎的短视频分享平台&#xff0c;每天都有大量的用户在抖音上分享自己的生活点滴和创意作品。对于开发者而言&#xff0c;如何获取并解析抖音上的视频内容&#xff0c;是一项极具挑战性的任务。本文将详细介绍抖音详情API&#xff0c;以及如何使用它来…...

SpringBoot中实现阿里云OSS对象存储

背景 在业务中我们往往需要上传文件如图片&#xff0c;文件上传&#xff0c;是指将本地图片、视频、音频等文件上传到服务器上&#xff0c;可以供其他用户浏览或下载的过程。文件上传在项目中应用非常广泛&#xff0c;我们经常发抖音、发朋友圈都用到了文件上传功能。 实现文件…...

大型语言模型 (LLM)全解读

一、大型语言模型&#xff08;Large Language Model&#xff09;定义 大型语言模型 是一种深度学习算法&#xff0c;可以执行各种自然语言处理 (NLP) 任务。 大型语言模型底层使用多个转换器模型&#xff0c; 底层转换器是一组神经网络。 大型语言模型是使用海量数据集进行训练…...

Unity - gamma space下还原linear space效果

文章目录 环境目的环境问题实践结果处理要点处理细节【OnPostProcessTexture 实现 sRGB 2 Linear 编码】 - 预处理【封装个简单的 *.cginc】 - shader runtime【shader需要gamma space下还原记得 #define _RECOVERY_LINEAR_IN_GAMMA】【颜色参数应用前 和 颜色贴图采样后】【灯…...

Rabbitmq调用FeignClient接口失败

文章目录 一、框架及逻辑介绍1.背景服务介绍2.问题逻辑介绍 二、代码1.A服务2.B服务3.C服务 三、解决思路1.确认B调用C服务接口是否能正常调通2.确认B服务是否能正常调用A服务3.确认消息能否正常消费4.总结 四、修改代码验证1.B服务异步调用C服务接口——失败2.将消费消息放到C…...

专业120+总分400+海南大学838信号与系统考研高分经验海大电子信息与通信

今年专业838信号与系统120&#xff0c;总分400&#xff0c;顺利上岸海南大学&#xff0c;这一年的复习起起伏伏&#xff0c;但是最后还是坚持下来的&#xff0c;吃过的苦都是值得&#xff0c;总结一下自己的复习经历&#xff0c;希望对大家复习有帮助。首先我想先强调一下专业课…...

如何区分 html 和 html5?

HTML&#xff08;超文本标记语言&#xff09;和HTML5在很多方面都存在显著的区别。HTML5是HTML的最新版本&#xff0c;引入了许多新的特性和元素&#xff0c;以支持更丰富的网页内容和更复杂的交互。以下是一些区分HTML和HTML5的关键点&#xff1a; 新特性与元素&#xff1a;H…...

Ps:将文件载入堆栈

Ps菜单&#xff1a;文件/脚本/将文件载入堆栈 Scripts/Load Files into Stack 将文件载入堆栈 Load Files into Stack脚本命令可用于将两个及以上的文件载入到同一个 Photoshop 新文档中。 载入的每个文件都将成为独立的图层&#xff0c;并使用其原始文件名作为图层名。 Photos…...

【格密码基础】:补充LWE问题

目录 一. LWE问题的鲁棒性 二. LWE其他分布选择 三. 推荐文献 四. 附密码学人心中的顶会 一. LWE问题的鲁棒性 robustness&#xff0c;翻译为鲁棒性 已有的论文表明&#xff0c;及时敌手获取到部分关于秘密和error的信息&#xff0c;LWE问题依旧是困难的&#xff0c;这能…...

【C++入门到精通】特殊类的设计 |只能在堆 ( 栈 ) 上创建对象的类 |禁止拷贝和继承的类 [ C++入门 ]

阅读导航 引言一、特殊类 --- 不能被拷贝的类1. C98方式&#xff1a;2. C11方式&#xff1a; 二、特殊类 --- 只能在堆上创建对象的类三、特殊类 --- 只能在栈上创建对象的类四、特殊类 --- 不能被继承的类1. C98方式2. C11方法 总结温馨提示 引言 在面向对象编程中&#xff0…...

VMware虚拟机部署Linux Ubuntu系统

本文介绍基于VMware Workstation Pro虚拟机软件&#xff0c;配置Linux Ubuntu操作系统环境的方法。 首先&#xff0c;我们需要进行VMware Workstation Pro虚拟机软件的下载与安装。需要注意的是&#xff0c;VMware Workstation Pro软件是一个收费软件&#xff0c;而互联网中有很…...

RFID标签:数字时代的智能身份

在数字时代&#xff0c;RFID标签&#xff08;Radio-Frequency Identification&#xff09;成为物联网&#xff08;IoT&#xff09;中不可或缺的一环。作为一种小巧却功能强大的设备&#xff0c;RFID标签在各个领域的应用不断扩展&#xff0c;为我们的生活和工作带来了新的可能性…...

《动手学深度学习(PyTorch版)》笔记3.2

注&#xff1a;书中对代码的讲解并不详细&#xff0c;本文对很多细节做了详细注释。另外&#xff0c;书上的源代码是在Jupyter Notebook上运行的&#xff0c;较为分散&#xff0c;本文将代码集中起来&#xff0c;并加以完善&#xff0c;全部用vscode在python 3.9.18下测试通过。…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

【实施指南】Android客户端HTTPS双向认证实施指南

&#x1f510; 一、所需准备材料 证书文件&#xff08;6类核心文件&#xff09; 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...

MLP实战二:MLP 实现图像数字多分类

任务 实战&#xff08;二&#xff09;&#xff1a;MLP 实现图像多分类 基于 mnist 数据集&#xff0c;建立 mlp 模型&#xff0c;实现 0-9 数字的十分类 task: 1、实现 mnist 数据载入&#xff0c;可视化图形数字&#xff1b; 2、完成数据预处理&#xff1a;图像数据维度转换与…...