c/c++ 深拷贝和浅拷贝

深拷贝与浅拷贝

深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是对象复制的两种不同方式,它们涉及到对象成员数据的复制方式和内存管理。

  • 浅拷贝(Shallow Copy):
    浅拷贝是指将一个对象的成员值简单地复制到另一个对象,包括指针类型的成员变量。浅拷贝只复制指针的值,而不会为指针指向的数据分配新的内存空间。这意味着原始对象和副本对象将共享同一份数据。如果其中一个对象修改了共享的数据,将影响到其他对象。
    在这里插入图片描述

  • 深拷贝(Deep Copy):
    深拷贝是指复制对象的每个成员,包括指针类型的成员变量。深拷贝会为每个指针类型的成员变量分配独立的内存空间,并将原始对象指针指向的数据复制到新分配的内存中。这样,原始对象和副本对象拥有各自独立的数据副本,对其中一个对象的修改不会影响到其他对象。
    在这里插入图片描述

  • 深拷贝和浅拷贝的选择取决于对象的成员数据类型和应用场景。对于简单的数据类型或者不涉及动态内存分配的对象,浅拷贝可能足够满足需求。但对于包含指针类型成员或动态分配内存的对象,通常需要使用深拷贝来确保对象之间的独立性。

  • 在C++中,可以通过自定义拷贝构造函数、赋值运算符重载或使用智能指针等方式来实现深拷贝。C语言中需要手动进行内存分配和复制操作,通过手动分配内存、复制数据并管理内存释放来实现深拷贝。

c语言深拷贝和浅拷贝

在C 语言中,没有像 C++ 中那样提供内置的深拷贝和浅拷贝的机制。在 C 语言中,需要手动编写代码来实现深拷贝和浅拷贝。

  • 浅拷贝(Shallow Copy):
    在 C 语言中,浅拷贝可以通过简单地将一个结构体或数组的成员值赋值给另一个结构体或数组来实现。这将导致两个对象共享相同的内存数据,包括指针类型的成员变量。如果其中一个对象修改了共享的数据,将影响到其他对象。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char* name;
    int age;
} Person;

int main() {
    Person person1;
    person1.name = malloc(sizeof(char) * 10);
    strcpy(person1.name, "John");
    person1.age = 25;

    Person person2 = person1;  // 浅拷贝

    // 修改 person2 的值
    person2.name = malloc(sizeof(char) * 10);
    strcpy(person2.name, "Alice");
    person2.age = 30;

    // 输出 person1 和 person2 的值
    printf("person1: name=%s, age=%d\n", person1.name, person1.age);
    printf("person2: name=%s, age=%d\n", person2.name, person2.age);

    // 释放内存
    free(person1.name);
    free(person2.name);

    return 0;
}

在上述示例中,通过将 person1 的成员值赋值给 person2,实现了浅拷贝。由于两个对象共享相同的内存数据,对其中一个对象的修改会影响另一个对象。

  • 深拷贝(Deep Copy):
    在 C 语言中,深拷贝需要手动进行内存分配和数据复制。对于包含指针类型成员变量的结构体或数组,需要为每个指针类型的成员变量分配独立的内存空间,并将原始对象指针指向的数据复制到新分配的内存中。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char* name;
    int age;
} Person;

// 深拷贝的函数
void deepCopyPerson(Person* dest, const Person* src) {
    dest->name = malloc(sizeof(char) * (strlen(src->name) + 1));
    strcpy(dest->name, src->name);
    dest->age = src->age;
}

int main() {
    Person person1;
    person1.name = malloc(sizeof(char) * 10);
    strcpy(person1.name, "John");
    person1.age = 25;

    Person person2;
    deepCopyPerson(&person2, &person1);  // 深拷贝

    // 修改 person2 的值
    free(person2.name);
    person2.name = malloc(sizeof(char) * 10);
    strcpy(person2.name, "Alice");
    person2.age = 30;

    // 输出 person1 和 person2 的值
    printf("person1: name=%s, age=%d\n", person1.name, person1.age);
    printf("person2: name=%s, age=%d\n", person2.name, person2.age);

    // 释放内存
    free(person1.name);
    free(person2.name);

    return 0;
}

在上述示例中,通过自定义的函数 deepCopyPerson,实现了深拷贝。该函数手动为 person2 的成员变量分配独立的内存,并将原始对象的数据复制到新分配的内存中。这样,原始对象和副本对象拥有各自独立的数据副本。在使用完后,还需要手动释放内存。

c++深拷贝和浅拷贝

在 C++ 中,可以通过拷贝构造函数赋值运算符来实现深拷贝和浅拷贝。

  • 浅拷贝(Shallow Copy):
    (1)默认情况下,C++ 提供的拷贝构造函数和赋值运算符执行的是浅拷贝操作,即简单地复制成员变量的值。
    (2)对于指针类型的成员变量,直接复制指针的值,这样两个对象将共享相同的内存数据。
class ShallowCopy {
public:
    ShallowCopy(int* data, int size) {
        this->data = data;
        this->size = size;
    }

    // 默认拷贝构造函数执行浅拷贝
    ShallowCopy(const ShallowCopy& other) {
        data = other.data;  // 复制指针的值
        size = other.size;
    }

    // 默认赋值运算符执行浅拷贝
    ShallowCopy& operator=(const ShallowCopy& other) {
        if (this != &other) {
            data = other.data;  // 复制指针的值
            size = other.size;
        }
        return *this;
    }

private:
    int* data;
    int size;
};

在上述示例中,ShallowCopy 类具有一个指针类型的成员变量 data 和一个整数 size。默认的拷贝构造函数和赋值运算符执行浅拷贝,直接复制指针的值,这样两个对象将共享相同的数据。

  • 深拷贝(Deep Copy):
    (1)在自定义拷贝构造函数和赋值运算符时,先为新对象分配独立的内存空间。
    (2)将原始对象的数据复制到新的内存空间中,确保每个对象拥有独立的数据副本。
class DeepCopy {
public:
    DeepCopy(int* data, int size) {
        this->data = new int[size];
        for (int i = 0; i < size; ++i) {
            this->data[i] = data[i];
        }
        this->size = size;
    }

    // 自定义拷贝构造函数执行深拷贝
    DeepCopy(const DeepCopy& other) {
        data = new int[other.size];
        for (int i = 0; i < other.size; ++i) {
            data[i] = other.data[i];
        }
        size = other.size;
    }

    // 自定义赋值运算符执行深拷贝
    DeepCopy& operator=(const DeepCopy& other) {
        if (this != &other) {
            delete[] data;
            data = new int[other.size];
            for (int i = 0; i < other.size; ++i) {
                data[i] = other.data[i];
            }
            size = other.size;
        }
        return *this;
    }

    ~DeepCopy() {
        delete[] data;
    }

private:
    int* data;
    int size;
};

在上述示例中,DeepCopy 类具有一个指针类型的成员变量 data 和一个整数 size。自定义的拷贝构造函数和赋值运算符执行深拷贝,为新对象分配独立的内存空间,并将原始对象的数据复制到新的内存空间中,确保每个对象拥有独立的数据副本。

需要注意的是,在自定义拷贝构造函数和赋值运算符时,还需要注意内存管理,确保在对象销毁时释放已分配的内存,以避免内存泄漏。在示例中,通过在析构函数中释放 data 数组所占用的内存。

参考

  • AI。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

投资400亿美元!人工智能或将诞生超级大国

据外媒报道&#xff0c;沙特阿拉伯政府计划设立约 400 亿美元的基金来投资人工智能&#xff0c;如此规模的基金将成为迄今为止全球最大的专注于人工智能发展的基金之一。 据知情人士透露&#xff0c;该基金长期以来一直被硅谷用来为科技初创企业提供资金&#xff0c;甚至一度是…

在线教育话术(1W字精选)

产品结构图 Nginx实现代理 问&#xff1a;我们在本机的host文件中配置了域名映射&#xff0c;都是同一个服务器。我们只需要输入对应的域名就可以到对应的界面&#xff0c;这是怎么实现的&#xff1f; 答&#xff1a;主要就是通过Nginx反向代理来实现的&#xff0c;Nginx会先…

【go语言开发】性能分析工具pprof使用

本文主要介绍如何在项目中使用pprof工具。首先简要介绍pprof工具的作用&#xff1b;然后介绍pprof的应用场景&#xff0c;主要分为工具型应用和服务型应用。最后数据分析项目&#xff0c;先采集项目信息&#xff0c;再可视化查看 文章目录 前言应用场景工具型应用服务型应用 数…

基于补丁方式修复 nginx漏洞 缓冲区错误漏洞(CVE-2022-41741)、越界写入漏洞(CVE-2022-41742)

nginx1.22.0版本漏洞 CVE-2022-41741 、CVE-2022-41742 漏洞描述 1、nginx 缓冲区错误漏洞(CVE-2022-41741) 此插件基于版本检测&#xff0c;有可能误报&#xff0c;未开启 MP4 模块的nginx属于误报&#xff0c;请忽略该漏洞。Nginx是美国Nginx公司的一款轻量级Web服务器/反…

Jmeter Ultimate Thread Group 和 Stepping Thread Group

线程组&#xff1a;使用复杂场景的性能测试 有时候我们做性能测试时&#xff0c;只依靠自带的线程组&#xff0c;显示满足不了性能测试中比较复杂的场景&#xff0c;下面这两种线程组可以帮助你很好的完成复杂的场景 第一种&#xff1a;Stepping Thread Group 在取样器错误后…

2024年【安全员-C证】考试资料及安全员-C证新版试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 安全员-C证考试资料是安全生产模拟考试一点通生成的&#xff0c;安全员-C证证模拟考试题库是根据安全员-C证最新版教材汇编出安全员-C证仿真模拟考试。2024年【安全员-C证】考试资料及安全员-C证新版试题 1、【多选题…

Java基础入门day17

day17 复习二分查找java package com.saas; ​ public class BinarySearch { ​public static void main(String[] args) {int[] nums {12, 21, 33, 77, 89, 90}; ​System.out.println(binarySearch(nums, 21));} ​public static int binarySearch(int[] arrs, int target)…

springBoot项目,无配置中心,怎么实现类似功能

实现EnvironmentPostProcessor import cn.hutool.http.HttpUtil; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.boot.env.YamlPropertySourceLoader; import org.springfr…

springboot企业级抽奖项目业务一(登录模块)

开发流程 该业务基于rouyi生成好了mapper和service的代码&#xff0c;现在需要在controller层写接口 实际操作流程&#xff1a; 看接口文档一>controller里定义函数一>看给出的工具类一>补全controller里的函数一>运行测试 接口文档 在登录模块有登录和登出方…

在windows上安装Jenkins

jenkins安装 下载jenkins 官网&#xff1a;Jenkins download and deployment 官方文档说明&#xff1a;Jenkins User Documentation 安装jenkins1.点击下载好的安装包&#xff0c;点击Next 2.选择一个安装路径 如果系统是windows家庭版打不开策略就创建一个txt文件&#xff0c…

Android分区存储到底该怎么做

文章目录 一、Android存储结构二、什么是分区存储&#xff1f;三、私有目录和公有目录三、存储权限和分区存储有什么关系&#xff1f;四、我们应该该怎么做适配&#xff1f;4.1、利用File进行操作4.2、使用MediaStore操作数据库 一、Android存储结构 Android存储分为内部存储和…

NBlog Java定时任务-备份MySQL数据

NBlog部署维护流程记录&#xff08;持续更新&#xff09;&#xff1a;https://blog.csdn.net/qq_43349112/article/details/136129806 为了避免服务器被攻击&#xff0c;给博客添加了一个MySQL数据备份功能。 此功能是配合博客写的&#xff0c;有些方法直接用的已有的&#xf…

Matlab中inv()函数的使用

在Matlab中&#xff0c;inv()函数是用来求解矩阵的逆矩阵的函数。逆矩阵是一个与原矩阵相乘后得到单位矩阵的矩阵。在数学中&#xff0c;矩阵A的逆矩阵通常用A^-1表示。 什么是逆矩阵 在数学中&#xff0c;对于一个n阶方阵A&#xff0c;如果存在一个n阶方阵B&#xff0c;使得…

Gradio官方文档

文章目录 构建您的第一个demo分享您的demo进度条受密码保护的应用程序The Interface class&#xff08;接口类&#xff09;Components Attributes&#xff08;组件属性&#xff09;多个输入和输出组件图像示例嵌套列表描述性内容手风琴中的附加输入The 4 Kinds of Gradio Inter…

Android: Gradle 命令

一、查看整个项目依赖传递关系 x.x.x (*) 该依赖已经有了&#xff0c;将不再重复依赖。x.x.x -> x.x.x 该依赖的版本被箭头所指的版本代替。x.x.x -> x.x.x(*) 该依赖的版本被箭头所指的版本代替&#xff0c;并且该依赖已经有了&#xff0c;不再重复依赖。 1. gradlew ap…

冰岛人[天梯赛]

文章目录 题目描述思路AC代码 题目描述 输入样例 15 chris smithm adam smithm bob adamsson jack chrissson bill chrissson mike jacksson steve billsson tim mikesson april mikesdottir eric stevesson tracy timsdottir james ericsson patrick jacksson robin patrickss…

2024年最新Anaconda3 2024版中Jupyter Notebook安装

一、 Anaconda3 2024版下载 1.下载&#xff1a;Free Download | Anaconda 2.等待 解释&#xff1a;默认选择等等下载 &#xff0c;时间可能数分钟 3.安装 解释&#xff1a;打开刚刚下载的Anaconda Navigator&#xff0c;并如图安装低版本&#xff0c;高版本会直接报错 4. …

[zdyz]FreeRTOS笔记

FreeRTOS基础知识 1&#xff0c;任务调度器简介 调度器就是使用相关的调度算法来决定当前需要执行的哪个任务 抢占式调度 时间片调度 协程式调度 略 2&#xff0c;任务状态 运行态 正在执行的任务&#xff0c;该任务就处于运行态&#xff0c;注意在STM32中&#xff0c;同…

【Web】记录[长城杯 2022 高校组]b4bycoffee题目复现

目录 前言 环境准备 简单分析 EXP(两种打法) 生成Payload 恶意类 ①Spring命令执行回显类 ②Filter型内存马 前言 本地jar包运行打通了&#xff0c;远程500&#xff0c;nss靶机有问题&#xff0c;换了bugku就可( 主要记录下做题过程&#xff0c;纯菜狗&#xff0c;小…

深圳库卡机器人KR460控制柜维修快速解决

一、库卡机器人KR460控制柜常见故障类型 库卡机器人KR460控制柜可能出现的故障类型多种多样&#xff0c;常见的包括电源故障、通信故障、过热保护以及电路板损坏等。这些故障可能导致机器人不能启动、运行不稳定或突然停机等问题。 二、库卡机器人KR460控制柜维修前的准备 在开…