研一寒假C++复习笔记--深拷贝和浅拷贝代码实例

news2024/10/1 15:29:22

目录

1--深拷贝和浅拷贝的基础概念

2--浅拷贝的代码实例

3--深拷贝代码实例

4--参考


1--深拷贝和浅拷贝的基础概念

① 浅拷贝:简单的赋值拷贝操作;

② 深拷贝:在堆区重新申请空间,进行拷贝操作;

2--浅拷贝的代码实例

# include <iostream>

class Person{

public:
    // 有参构造函数
    Person(int age, int height){
        Age = age;
        Height = new int(height); // 存放在堆区
        std::cout << "有参构造函数的调用" << std::endl;
    }

    // 模仿编译器默认实现的浅拷贝构造函数
    Person(const Person &p){
        Age = p.Age;
        Height = p.Height; // 编译器默认实现浅拷贝
        std::cout << "拷贝构造函数的调用" << std::endl;
    }
    
    // 析构函数
    ~Person(){
        if(Height != NULL){ // 手动释放堆区的数据
            delete Height;
            Height = NULL; 
        }       
        std::cout << "析构函数的调用" << std::endl;
    }

    int Age;
    int *Height;
};

int main(){
    Person p1(23, 180);
    std::cout << "p1.Age = " << p1.Age << " p1.Height = " << *p1.Height << std::endl; // 23, 180
    Person p2(p1);
    std::cout << "p2.Age = " << p2.Age << " p1.Height = " << *p2.Height << std::endl; // 23, 180
    return 0;
}

        编译器默认实现的浅拷贝构造函数如下:

    // 模仿编译器默认实现的浅拷贝构造函数
    Person(const Person &p){
        Age = p.Age;
        Height = p.Height; // 编译器默认实现浅拷贝
        std::cout << "拷贝构造函数的调用" << std::endl;
    }

        在创建对象p1时,有参构造函数在堆区申请了内存空间来存储指针 Height 指向的数据;

        在创建对象p2时,使用编译器默认的浅拷贝构造函数,这时p2对象的 Height 也会指向与p1相同的堆区空间;

        但在使用析构函数销毁堆区的数据时,会出现重复销毁的问题,即 p1 和 p2 会重复销毁堆区的同一块内存数据,从而出现 bug 。

3--深拷贝代码实例

        人为定义深拷贝构造函数,可以避免上面浅拷贝带来的堆区数据重复被销毁的问题;

# include <iostream>

class Person{

public:
    // 有参构造函数
    Person(int age, int height){
        Age = age;
        Height = new int(height); // 存放在堆区
        std::cout << "有参构造函数的调用" << std::endl;
    }

    // 人为实现拷贝构造函数,避免浅拷贝
    Person(const Person &p){
        Age = p.Age;
        // Height = p.Height; // 编译器默认实现浅拷贝
        Height = new int (*p.Height);  // 人为实现深拷贝
        std::cout << "拷贝构造函数的调用" << std::endl;
    }
    
    // 析构函数
    ~Person(){
        if(Height != NULL){ // 手动释放堆区的数据
            delete Height;
            Height = NULL; 
        }       
        std::cout << "析构函数的调用" << std::endl;
    }

    int Age;
    int *Height;
};

int main(){
    Person p1(23, 180);
    std::cout << "p1.Age = " << p1.Age << " p1.Height = " << *p1.Height << std::endl; // 23, 180
    Person p2(p1);
    std::cout << "p2.Age = " << p2.Age << " p1.Height = " << *p2.Height << std::endl; // 23, 180
    return 0;
}

        人为实现的深拷贝构造函数如下:

    // 人为实现拷贝构造函数,避免浅拷贝
    Person(const Person &p){
        Age = p.Age;
        // Height = p.Height; // 编译器默认实现浅拷贝
        Height = new int (*p.Height);  // 人为实现深拷贝
        std::cout << "拷贝构造函数的调用" << std::endl;
    }
    

        与编译器默认实现的浅拷贝构造函数不同,深拷贝在堆区重新申请空间来进行拷贝操作,这样不同对象指向的堆区空间不同,在利用析构函数销毁对象时也不会出现重复销毁的问题;

Height = p.Height; // 编译器默认实现浅拷贝
Height = new int (*p.Height);  // 人为实现深拷贝

4--参考

深拷贝和浅拷贝代码讲解

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

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

相关文章

CUDA中的统一内存

文章目录1. Unified Memory Introduction1.1. System Requirements1.2. Simplifying GPU Programming1.3. Data Migration and Coherency1.4. GPU Memory Oversubscription1.5. Multi-GPU1.6. System Allocator1.7. Hardware Coherency1.8. Access Counters2. Programming Mode…

格子玻尔兹曼法介绍

1 LBM简介格子玻尔兹曼法&#xff08;Lattice Boltzmann Method&#xff09;简称LBM&#xff0c;是一种CFD算法&#xff0c;可求解流动、传热等常见CFD问题。LBM基于格子玻尔兹曼方程&#xff08;LBE&#xff09;&#xff0c;从介观尺度&#xff08;mesoscope&#xff09;描述了…

Android Jetpack组件之WorkManager后台任务管理的介绍与使用(二)

一、介绍 通过上一篇文&#xff0c;Android Jetpack组件之WorkManager后台任务管理的介绍与使用(一)_蜗牛、Z的博客-CSDN博客 我们可以弄清楚workmanager从接入到使用的基本流程。基本可以满足我们日常。那只是简单的入门。如果遇到更复杂的功能&#xff0c;那简单的就无法满…

集中供热调度系统天然气仪表内网仪表图像识别案例

一、项目需求 出于能耗采集与冬季集中供暖工作的节能和能耗分析需要&#xff0c;要采集现场的6块天然气表计&#xff0c;并存储进入客户的mySQL数据库中&#xff0c;现场采集的表计不允许接线&#xff0c;且网络环境为内网环境&#xff0c;需要采集表计数据并存入数据库&#…

Java笔记-泛型的使用

参考&#xff1a; Java 泛型&#xff0c;你了解类型擦除吗&#xff1f; 泛型的使用 1、泛型的定义 可以广泛使用的类型&#xff0c;一种较为准确的说法就是为了参数化类型&#xff0c;或者说可以将类型当作参数传递给一个类或者是方法。 2、泛型的使用 2.1泛型类 public c…

FreeRTOS信号量 | FreeRTOS十

目录 说明&#xff1a; 一、信号量 1.1、信号量简介 1.2、信号量特点 二、二值信号量 2.1、二值信号量简介 2.2、获取与释放二值信号量函数 2.3、二值信号量使用过程与相关API函数 2.4、创建二值信号量函数了解 2.5、释放二值信号量了解 2.6、获取二值信号量了解 三…

Python语言零基础入门教程(十三)

Python 字典(Dictionary) 字典是另一种可变容器模型&#xff0c;且可存储任意类型对象。 字典的每个键值 key:value 对用冒号 : 分割&#xff0c;每个键值对之间用逗号 , 分割&#xff0c;整个字典包括在花括号 {} 中 ,格式如下所示&#xff1a; d {key1 : value1, key2 : …

企业进存销管理系统

技术&#xff1a;Java、JSP等摘要&#xff1a;随着当今世界计算机技术的飞速发展&#xff0c;计算机在企业管理中应用的普及&#xff0c;利用计算机实现企业进销存管理势在必行。本系统结合公司实际的进销存制度&#xff0c;通过对本公司的供应商、客户、商品、进货、销售、进销…

分享77个JS菜单导航,总有一款适合您

分享77个JS菜单导航&#xff0c;总有一款适合您 77个JS菜单导航下载链接&#xff1a;https://pan.baidu.com/s/1e_384_1KC2oSTDy7AaD3og?pwdzkw6 提取码&#xff1a;zkw6 Python采集代码下载链接&#xff1a;https://wwgn.lanzoul.com/iKGwb0kye3wj class ChinaZJsSeleni…

大型医院分诊系统源码 排队叫号系统源码 C#源码

医院排队分诊叫号系统用于医院各门诊科室&#xff0c;实现分诊、排队叫号、显示叫号、刷卡签到等功能。可有效地解决病人就诊时排队无序、医生工作量不平衡、就诊环境嘈杂等问题。 医院分诊叫号系统由分诊管理端、大屏显示端、医生呼叫端三大模块组成。 开发环境&#xff1a;…

第01章_数据库概述

第01章_数据库概述 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 1. 为什么要使用数据库 持久化(persistence)&#xff1a;把数据保存到可掉电式存储设备中以供之后使用。大多数情况下&#x…

4年外包终上岸,我只能说这类公司能不去就不去..

我大学学的是计算机专业&#xff0c;毕业的时候&#xff0c;对于找工作比较迷茫&#xff0c;也不知道当时怎么想的&#xff0c;一头就扎进了一家外包公司&#xff0c;一干就是4年。现在终于跳槽到了互联网公司了&#xff0c;我想说的是&#xff0c;但凡有点机会&#xff0c;千万…

SpringBoot 全局异常处理用法及原理

SpringBoot 全局异常处理用法及原理 Springboot或springMVC项目中&#xff0c; 我们一般会设置一个全局异常处理&#xff0c; 来对异常进行兜底。 业务代码执行过程中抛出的异常&#xff0c; 如果业务逻辑没有主动捕获&#xff0c;那么异常就会一直往上抛&#xff0c;最后进入…

RockChip MPP编码

概述瑞芯微提供的媒体处理软件平台&#xff08;Media Process Platform&#xff0c;简称 MPP&#xff09;是适用于瑞芯微芯片系列的通用媒体处理软件平台。该平台对应用软件屏蔽了芯片相关的复杂底层处理&#xff0c;其目的是为了屏蔽不同芯片的差异&#xff0c;为使用者提供统…

使用java开发连连看游戏

技术&#xff1a;Java等摘要&#xff1a;社会在发展&#xff0c;人类在进步&#xff0c;生活质量保证之余&#xff0c;各种游戏蜂拥而起&#xff0c;越来越受到各界人士的追捧&#xff0c;比如老少适宜的斗地主&#xff0c;深受广大女性喜欢的节奏大师&#xff0c;受高智商人群…

Pandas——Series操作【建议收藏】

pandas——Series操作 作者&#xff1a;AOAIYI 创作不易&#xff0c;觉得文章不错或能帮助到你学习&#xff0c;可以点赞收藏评论哦 文章目录pandas——Series操作一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤1.创建Series2.从具体位置的Series中访问数据3.使…

FyListen——生命周期监听器(设计原理之理解生命周期)

FyListen——生命周期监听器&#xff08;设计原理之理解生命周期&#xff09; FyListen 的核心原理有两个&#xff1a; 通过子Fragment对Activity、Fragment进行生命周期监听Java8 接口特性 default 1. 什么是上下文Context 这是一个装饰器模式&#xff0c; ContextImpl 是 …

【ChatGPT说】我想给大家【编】一个故事,故事的主人公叫【架构师李肯】,故事的开头,还得从他那年买房说起。。。

大家好啊&#xff0c;我就是那个【天涯何处无知己&#xff0c;人穷陌路勿担忧】的架构师李肯&#xff01; 架构师李肯&#xff08;全网同名&#xff09; 在深圳白手起家&#xff0c;毕业不到4年实现一线城市核心地段的安家梦&#xff0c;从0开始谱写励志人生&#xff01;一个专…

一文手把手教你写一个 Makefile 文件

如果我们是在Linux下开发&#xff0c;那Makefile肯定要知道&#xff0c;不懂Makefile&#xff0c;面对较大的工程项目的时候就会比较麻烦&#xff0c;懂得利用开发工具将会大大提高我们的开发效率&#xff0c;也可以说Makefile是必须掌握的一项技能。 一、了解什么是 Makefile…

java集合框架内容整理

主要内容集合框架体系ArrayListLinkedListHashSetTreeSetLinkedHashSet内部比较器和外部比较器哈希表的原理List集合List集合的主要实现类有ArrayList和LinkedList&#xff0c;分别是数据结构中顺序表和链表的实现。另外还包括栈和队列的实现类&#xff1a;Deque和Queue。• Li…