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

news2024/11/23 23:57:05

深拷贝与浅拷贝

深拷贝(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。

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

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

相关文章

移动端滚轮插件mobile-select.js的使用记录

#小李子9479# 把文件下载放到static/mobile-select里面&#xff0c;如下图 分别引入js和css。 注意&#xff1a;一定要在页面加载完成后就初始化这个组件 &#xff0c;否则的话&#xff0c;第一次点击无效。

国内外主流智能驾驶芯片企业和技术介绍

英伟达依托积累多年的图形计算处理能力、GPU计算经验&#xff0c;布局智能驾驶芯片。 英伟达是全球最大的智能计算平台型公司&#xff0c;早期专注 PC 图形计算&#xff0c;后重点布局AI 领域&#xff0c;并在独立显卡、GPU等领域卓有成就。公司2006 年开发了基于 GPU 的「CUD…

算法沉淀——贪心算法五(leetcode真题剖析)

算法沉淀——贪心算法五 01.跳跃游戏 II02.跳跃游戏03.加油站04.单调递增的数字 01.跳跃游戏 II 题目链接&#xff1a;https://leetcode.cn/problems/jump-game-ii/ 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转…

AIGC——ComfyUI工作流搭建、导入与常用工作流下载

工作流 ComfyUI工作流是一个基于图形节点编辑器的工作流程&#xff0c;通过拖拽各种节点到画布上&#xff0c;连接节点之间的关系&#xff0c;构建从加载模型到生成图像的流程。每个节点代表一个与Stable Diffusion相关的模型或功能&#xff0c;节点之间通过连线传递图片信息。…

支小蜜校园防欺凌系统可以在厕所使用吗?

随着社会的进步和教育理念的更新&#xff0c;校园安全问题日益受到社会各界的关注。近年来&#xff0c;校园欺凌事件频发&#xff0c;给受害者的身心健康带来了严重影响&#xff0c;也给整个校园环境的和谐稳定带来了威胁。为此&#xff0c;许多学校开始引入校园防欺凌系统&…

详细分析Python模块中的雪花算法(附模板)

目录 前言1. 基本知识2. 模板3. Demo 前言 分布式ID的生成推荐阅读&#xff1a;分布式ID生成方法的超详细分析&#xff08;全&#xff09; 1. 基本知识 Snowflake 算法是一种用于生成全局唯一 ID 的分布式算法&#xff0c;最初由 Twitter 设计并开源 它被设计用于解决分布式…

设计模式|工厂模式

文章目录 1. 工厂模式的三种实现2. 简单工厂模式和工厂方法模式示例3. 抽象工厂模式示例4. 工厂模式与多态的关系5. 工程模式与策略模式的关系6. 面试中可能遇到的问题6.1 **工厂模式的概念是什么&#xff1f;**6.2 **工厂模式解决了什么问题&#xff1f;**6.3 **工厂模式的优点…

C++ 模板入门详解

目录 0. 模板引入 1.函数模板 1. 函数重载的缺点 2. 函数模板的概念和格式 2. 函数模板的实例化 2.1 隐式实例化&#xff1a;让编译器根据实参推演模板参数的实际类型 2.2 显式实例化&#xff1a;在函数名后的<>中指定模板参数的实际类型 2.3 函数模板参数的匹…

蓝桥杯刷题-替换字符

代码&#xff1a; 顺着题目意思写即可 sinput() nint(input()) for i in range(n):l, r, x, y input().split() if x not in s[int(l)-1:int(r)]: # 如果待替换字符不在区间内则跳过continueelse:# 找到待替换字符的位置&#xff0c;用replace函数进行替换ss[:int(l)-1]s[in…

Linux-docker安装数据库mysql

1、拉去mysql镜像&#xff1a; docker pull mysql2、创建容器挂载路径 mkdir -p /usr/local/jiuxiang/mysql/data # 数据存储位置 mkdir -p /usr/local/jiuxiang/mysql/logs # 日志存储位置 mkdir -p /usr/local/jiuxiang/mysql/conf # 配置文件3、启动容器 docker run -…

STL第一弹

2 STL初识 2.1 STL的诞生 长久以来&#xff0c;软件界一直希望建立一种可重复利用的东西 C的面向对象和泛型编程思想&#xff0c;目的就是复用性的提升 大多情况下&#xff0c;数据结构和算法都未能有一套标准,导致被迫从事大量重复工作为了建立数据结构和算法的一套标准,诞生…

MySQL的基本操作与增删改查管理操作

一、MySQL数据库sql语句 1.1 sql 命令 database数据库table表row行column列user用户select从数据表中获取数据updata更新数据库中的数据delete从数据库中删除数据insert into 向数据表插入数据create database创建新数据库alter database修改数据库create table创建新表alter…

蓝桥杯 2023 省B 飞机降落

首先&#xff0c;这题要求的数据量比较少&#xff0c;我们可以考虑考虑暴力解法。 这题可能难在很多情况的考虑&#xff0c;比如说&#xff1a; 现在时间是10&#xff0c;有个飞机20才到&#xff0c;我们是可以干等10分钟。 #include <iostream> #include <…

【机器学习300问】39、高斯分布模型如何实现异常检测?

一、异常检测是什么&#xff1f; &#xff08;1&#xff09;举几个例子 ① 信用卡交易异常检测 在信用卡交易数据分析中&#xff0c;如果某个用户的消费习惯通常是小额且本地化消费&#xff0c;那么突然出现一笔大额且跨国的交易就可能被标记为异常。 ② 电机温度异常检测 在电…

echart trigger 为 axis 的时候不显示 tooltip 解决办法

echart trigger 为 axis 的时候不显示 tooltip 解决办法 在项目 vitetsvue3 中使用 echart 显示了一个曲线图&#xff1a; 但当把图表的 trigger 设置成 axis 的时候&#xff0c;鼠标扫过并不显示具体的数值&#xff0c;如上图所示。 但 trigger item 的时候是正常的。 解决…

Docker Desktop 安装 ClickHouse 超级简单教程

Docker desktop 安装 clickhouse 超级简单 文章目录 Docker desktop 安装 clickhouse 超级简单 什么是 Docker &#xff1f;安装下准备安装Docker配置安装 ClickHouse配置数据库密码DBeaver 测试创建表总结 什么是 Docker &#xff1f; 下载 Docker desktop Docker Desktop …

[蓝桥杯 2015 省 B] 生命之树

水一水的入门树形DP #include<iostream> #include<algorithm> #include<vector> using namespace std; using ll long long; #define int long long const int N 2e610; const int inf 0x3f3f3f3f; const int mod 1e97;int n; int w[N]; vector<vecto…

Node.js快速入门:搭建基础Web服务器与实现CRUD及登录功能

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

Word2vec 学习笔记

word2vec 学习笔记 0. 引言1. Word2vec 简介1-1. CBOW1-2. SG 2. 实战 0. 引言 最近研究向量检索&#xff0c;看到有同事使用 MeCab、Doc2Vec&#xff0c;所以把 Word2vec 这块知识学习一下。 1. Word2vec 简介 Word2vec 即 word to vector&#xff0c;顾名思义&#xff0c;…

在MongoDB建模1对N关系的基本方法

“我在 SQL 和规范化数据库方面拥有丰富的经验&#xff0c;但我只是 MongoDB 的初学者。如何建立一对 N 关系模型&#xff1f;” 这是我从参加 MongoDB 分享日活动的用户那里得到的最常见问题之一。 我对这个问题没有简短的答案&#xff0c;因为方法不只有一种&#xff0c;还有…