【c++】拷贝构造函数中的深拷贝和浅拷贝

C++简单类(构造函数,析构函数以及拷贝构造函数)的实现 C++简单类的实现,包括构造函数,析构函数以及拷贝构造函数 立即下载

一、什么是浅拷贝?什么是深拷贝?

以下面这个函数为例,如图:

class Example {
public:
    int* data;
    int size;

    // 普通构造函数:初始化数组数据
    Example(int n) : size(n) {
        data = new int[size];
        // 给数组赋值:[0,1,2,3]
        for (int i = 0; i < size; i++) {
            data[i] = i;
        }
    }

    // 拷贝构造函数
    Example(const Example& other) : size(other.size) {
        data = new int[size];
        std::copy(other.data, other.data + size, data); //深拷贝
        cout << "拷贝构造函数\n";
    }

    // 打印数组内容
    void print() {
        for (int i = 0; i < size; i++) {
            cout << data[i] << " ";
        }
        cout << endl;
    }

    ~Example() {
        delete[] data;
    }
};

这个函数实现的就是深拷贝,是需要我们手动去实现的。如果我们不去实现拷贝构造函数,编译器默认会生成浅拷贝的拷贝构造函数,类似如下代码,如图:

    Example(const Example& other) : size(other.size) {
        data = other.data;//浅拷贝
    }

浅拷贝的缺点:

  • data = other.data 只是让新对象的 data 指针指向 other.data 的内存地址,没有新分配内存;
  • 当原对象 / 新对象析构时,会重复释放同一块内存,导致程序崩溃;
  • 而我们的写法是深拷贝:先分配新内存,再拷贝数据,两个对象的 data 指向不同内存,互不影响。

二、深拷贝的写法

    Example(const Example& other) : size(other.size) {
        data = new int[size];
        std::copy(other.data, other.data + size, data); //深拷贝
        cout << "拷贝构造函数\n";
    }

在这里我们将other的size给到新对象的size,通过std::copy将原对象other的数组内容完整复制到新分配的内存中。(深拷贝的核心)

std::copy的作用?
作用是把一段连续内存中的数据,按顺序拷贝到另一段连续内存中。

这行代码,本质是:把 other.data 指向的数组中,从起始位置到 size 个元素的所有数据,拷贝到 data 指向的内存地址开始的位置。
参数逻辑:遵循 “左闭右开” 原则,[起始地址, 结束地址),总共拷贝 结束地址 - 起始地址 个元素;

除了std::copy,还有什么方法实现深拷贝?


1、手写 for 循环

Example(const Example& other) : size(other.size) {
    data = new int[size]; // 先分配内存
    // 替代std::copy的for循环
    for (int i = 0; i < size; i++) {
        data[i] = other.data[i]; // 逐个拷贝元素
    }
    std::cout << "拷贝构造函数\n";
}
  •  优点:新手易理解,无需依赖 <algorithm> 头文件;
  •  缺点:代码行数多,对于复杂类型 / 大数组,效率不如 std::copy(std::copy 是标准库优化过的);

2、C++11 及以上:std::uninitialized_copy

如果你的数组存储的是非基础类型(比如自定义类对象),std::uninitialized_copy 更合适 —— 它会在 “未初始化的内存” 上直接构造对象(而不是先默认构造再赋值),效率更高且更安全。

#include <memory> // 需包含这个头文件

Example(const Example& other) : size(other.size) {
    data = new int[size];
    // 替代std::copy,用法和std::copy几乎一致
    std::uninitialized_copy(other.data, other.data + size, data);
    std::cout << "拷贝构造函数\n";
}
  • 优点:对自定义对象更高效、更安全(避免默认构造 + 赋值的额外开销);
  • 缺点:需要依赖<memory> 头文件,对 int 等基础类型和 std::copy 效果无差异;
  • 适用场景:数组存储自定义类对象、追求极致内存效率时。

3、C 语言风格:memcpy(适合基础类型)

Example(const Example& other) : size(other.size) {
    data = new int[size];
    // 替代std::copy:按字节拷贝,sizeof(int)*size 是总字节数
    memcpy(data, other.data, sizeof(int) * size);
    std::cout << "拷贝构造函数\n";
}
  •  优点:基础类型拷贝效率极高(直接操作内存),代码简洁;
  •  缺点:
    1. 仅适用于 POD 类型(基础类型、简单结构体,无自定义构造 / 析构的类型);
    2. 用于自定义类对象时,会导致浅拷贝(比如对象里有 char* 指针,只会拷贝指针地址,而非字符串内容);
  •  适用场景:数组存储 int/char 等基础类型、追求极致性能时。

综上所述,std::copy是比较通用且适配所有类型的,同时标准库有一定优化,其他都是按需选择。

这里顺便说一下,std::copy和memcpy的区别

memcpy  —— 本质是按 “字节” 无脑拷贝

解释:它只拷贝字节,对自定义对象中的指针,仅复制指针的地址值,不拷贝指针指向的内容,因此是浅拷贝;

std::copy —— 本质是按 “类型” 调用赋值逻辑

解释:它按元素类型调用赋值运算符,只要你为自定义类型实现了深拷贝的 operator=(或拷贝构造),就能实现真正的深拷贝;

1.2 重叠因子:双重指数移动平均(Double Exponential Moving Average, DEMA)概念与Python实战 双重指数移动平均(Double Exponential Moving Average, DEMA)是一种改进的移动平均线指标,由Patrick Mulloy在1994年开发。相比传统的指数移动平均线(EMA),DEMA通过减少滞后性来提供更快的市场反应。它通过两次计算EMA并进行特殊组合来实现这一目标,可以在保持平滑性的同时减少滞后。 阅读详情

相关推荐

雪莉果的Axure原型工厂vol.006 中继器应用(二)——多选穿梭框

如果你用axure有一段时间了,那么你很快就能琢磨出一个大体设计流程,比如加一个中间过度的元件,来储存需要穿梭的内容;但是如果你再想一想,就会发现,这样做,似乎只能解决单选,那么多选需要怎么操作呢? 这时候,中继器就会告诉你,我还能做的更多。

weixin_43829792的博客 977

【深入理解C++】浅拷贝与深拷贝

1.前置知识 2.浅拷贝 3.深拷贝 4.总结

脚踏实地,仰望星空 2546

保姆级教程:从零到飞,用QGC地面站搞定PX4无人机全流程配置(含避坑指南)

本文提供了一份详细的QGC地面站使用教程,指导用户从零开始配置PX4无人机,涵盖固件烧录、传感器校准、遥控器设置及航点规划等关键步骤,并包含实用的避坑指南,帮助新手顺利完成首飞。

weixin_30329623的博客 221

深拷贝(C++基础)

在字符串、指针或者带有指针的对象拷贝的时候,如果只是简单做了赋值处理,不能拷贝一份指针指向的内存地址,只是拷贝了一份指向内存地址的指针,在对拷贝过的内存操作的时候就很可能带来一些错误,比如释放了拷贝过的内存,之前拷贝前的内存也会被释放,因为根本是同一个内存地址。运行后发现,输出都是lvx,并且在程序结束的时候会出线错误,说明lhx只有一个,并且被修改为lvx,而出现错误是因为在使用析构函数进行释放内存的时候,同一片内存被连续释放了。要习惯总是通过const引用去传递对象,但在某些情况下,复制可能更快。

weixin_45757750的博客 1231

Vc出现不能连接到一个或多个 vCenter server 系统:http://vcenter-vx.utibet.edu.cn:443/sdk

问题描述: 解决办法: esxi6.7的bug 第一种通过升级系统来解决问题 第二种是通过删除数据来解决 第一步:进入到esxi的shell 第二步查看其中的服务开启状态 第二步 df -h 第三步 /opt/vmware/vpostgres/current/bin/psql -d VCDB -U postgres 第四步 SELECT nspname || '.' || relname AS "relation", pg_size_pretty(pg_total_relation_size(C.oi

m0_49328536的博客 9901

ANPC三电平拓扑:两种调制方式解析

ANPC结构是基于“I”型NPC结构(下面讲NPC如不特殊说明,均指的是“I”型结构NPC)发展出来的一种改进型。我们在讲NPC结构的时候会谈到他的一个缺点就是损耗分布不均匀,会导致温升不均衡,进而限制模块的功率输出能力。而ANPC结构由于多了两个开关管以及相应的两个中性点换流回路(如下图),可以更加灵活任意的配置开关管可以使损耗没有那么的不均衡,从而能一定程度上提高模块的输出功率。ANPC拓扑结构图以及增加的环流回路。

IOTBOT的博客 9485

「C/C++ 01」 深拷贝和浅拷贝

一、概念 1. 浅拷贝2. 深拷贝3. 深浅拷贝问题4. 总结 二、在C++的类中实现深拷贝 1. 拷贝构造函数 中实现深拷贝2. operator= 中实现深拷贝

look_outs的博客 2983

5G无人机安全研究综述

国内多所高校提出混合信任模型,南京航空航天大学于2020年提出了起源信息感知的无人机网络信任模型[26],模型基于报文的完整性对报文创建和操作节点的行为评判并生成观测证据,收集证据进行信任评估,识别网络中的恶意节点并进行路由隔离,实现准确的对等信任评估。同时,5G技术的高速率、高可靠性、低时延等特点,能够为无人机提供实时高清图像回传,保证通信网络的稳定,拓展无人机飞控距离限制,丰富了5G无人机的应用场景。5G和无人机技术的融合,丰富了传统无人机的应用服务场景,然而5G无人机仍存在安全隐患。

weixin_70923796的博客 765

C++浅拷贝与深拷贝

浅拷贝:简单的赋值拷贝操作。 深拷贝:在堆区重新申请空间,进行拷贝操作。 C++中在对一个已知对象进行拷贝的时候,会调用类中的拷贝构造函数,如果程序员未定义拷贝构造函数,则会调用编译器默认的拷贝构造函数进行值拷贝! 看一个简单的例子: #include <iostream> using namespace std; class Person { public: Person() { /*默认构造函数*/ cout << "Person默认构造桉树的...

qq_42174306的博客 1万+

基于YOLOv13+CBAM注意力机制

本教程详细介绍了CBAM注意力机制的原理及其在YOLOv13中的集成方法。CBAM通过通道注意力和空间注意力两个模块,动态调整特征权重以增强模型性能。通道模块利用池化操作和共享MLP生成通道权重,空间模块则通过池化和卷积生成空间权重。教程提供了在YOLOv13中实现CBAM的具体步骤,包括模块代码定义、模型配置修改等关键环节,帮助开发者在目标检测任务中提升模型表现。

FJN110的博客 305

【OS】AUTOSAR OS系统调用产生Trap的过程详解

AUTOSAR OS系统调用产生Trap的过程详解

qq_36056498的博客 2438

【C++入门】深拷贝和浅拷贝详解

(1)当我们对复杂类型(结构体或者类)的对象进行初始化时,如果将同类型的对象A赋值给同类型的对象B,此时就涉及深拷贝和浅拷贝的问题;(2)如何定义拷贝的深和浅:浅拷贝就是把类/结构体的变量原封不动的赋值,不考虑指针变量;深拷贝就是在赋值时会对指针变量做处理;

weixin_42031299的博客 2604

10天冲刺国自然基金!用这套实战AI提示词指令教程,助你中标率翻倍!亲测DeepSeek和ChatGPT不好用

虽然以上国自然提示词指令经过反复实测,但并不是万能无脑帮你搞定所有,大模型AI的特性是你专业领域能力越强,它的智商表现就会更加强大,通过以上提示词教程的使用,大大提升中标概率是肯定的。还有就是大模型的使用上,不是市面上大家都说好的就一定适用,目前来看,Gemini和Claude的两个模型是非常适合国自然本子的修改的。在使用大模型进行国自然本子撰写修改时,首先是角色的设定,然后是目标和背景的描述,好用的提示词指令都是要经过无数次的实测,比对输出结果后又反复调整,达到最佳的效果状态的提示词指令。

智能AI让学术科研更容易 1247

C++中的拷贝构造函数(复制构造函数)以及涉及的深拷贝和浅拷贝问题

C++中的拷贝构造函数以及深浅拷贝。

m0_73968399的博客 2857

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

c++中的拷贝构造函数(深拷贝和浅拷贝)

浅拷贝适合无动态资源的简单对象(如仅包含基本类型的类)。深拷贝是管理动态资源时的必要手段。现代C++中,优先使用智能指针和RAII(Resource Acquisition Is Initialization)来避免手动深拷贝。

Ming_811的博客 962

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C++中的拷贝构造函数和深拷贝、浅拷贝,如何在C++中实现类和对象的序列化与反序列化?

在C++中实现类和对象的序列化和反序列化通常涉及将对象的状态转换为可以存储或传输的格式(如二进制或文本),以及从这种格式中恢复对象的状态。在这个例子中,拷贝构造函数执行的是浅拷贝,因为它只复制了 arr 指针,而没有复制指针指向的内存区域。拷贝构造函数是一种特殊的构造函数,它接受一个对其同类的常量引用作为参数,并用于初始化新创建的对象。在这个深拷贝的实现中,新对象的 arr 指针指向一块新的内存区域,这块内存区域是原对象数组数据的副本。深拷贝和浅拷贝主要涉及到对象内部的资源(如动态分配的内存)的拷贝方式。

Aaron的博客 1027

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

(C++中的浅拷贝和深拷贝)C++中某个类中有成员变量中有指向新开辟的堆空间要自己写构造函数和拷贝构造函数

涉及到浅拷贝和深拷贝 class Car { int m_price; char *m_name; public: Car(int price = 0, const char *name = NULL) :m_price(price){ if (name == NULL) r...

More reading and learning to become excellent 389

c++中的拷贝构造函数,浅拷贝,深拷贝

c++拷贝构造函数,深拷贝和浅拷贝

cyz322649的博客 1620

C++之深拷贝和浅拷贝

深拷贝和浅拷贝是什么?一文带你搞定。

qq_55958734的博客 1072

C++进阶之路:何为拷贝构造函数,深入理解浅拷贝与深拷贝(类与对象_中篇)

这意味着拷贝后的对象和原始对象共享同一块内存,当其中一个对象修改了内存中的值时,另一个对象也会受到影响。然而,当一个类拥有指针或引用等需要特别注意的成员变量时,编译器生成的默认拷贝构造函数不能保证正确的深拷贝,会导致浅拷贝问题和内存泄漏等问题。需要特别注意的是,如果类中包含指针或资源管理的成员变量(如动态分配的内存),则需要手动实现深拷贝以确保正确的对象复制和资源释放。因此,当类中存在指针或资源管理的成员变量时,通常需要自定义拷贝构造函数和赋值运算符,以实现深拷贝,避免出现潜在的问题。

Srlua的博客 2894

浅谈C++的浅拷贝和深拷贝问题

在C++中,浅拷贝和深拷贝是两种对象复制的方式,其中🐱浅拷贝(Shallow Copy)是指将一个对象的指赋值到另一个对象中,但只赋值对象的成员变量的值,并不对复制对象的动态分配内存(如堆内存)等外部资源,这也就意味着当原对象修改自己指向的外部资源时,可能会影响到另一个对象;这块的话其实也是浅拷贝问题的一种,因为我们没有在类中自定义赋值函数,C++编译器会调用它的默认赋值函数,做的也是数据的内存拷贝(即浅拷贝)。今天我们来谈谈C++的浅拷贝和深拷贝问题

icc_hhy的博客 1711

【C++】深入理解<深拷贝和浅拷贝>

本章的内容有: 什么是浅拷贝?什么是深拷贝?为什么要有深拷贝?如何理解浅拷贝和深拷贝?

翼同学 3059

C++深拷贝和浅拷贝(深复制和浅复制)完全攻略

C++深拷贝和浅拷贝(深复制和浅复制)完全攻略 对于基本类型的数据以及简单的对象,它们之间的拷贝非常简单,就是按位复制内存。例如: class Base{ public: Base(): m_a(0), m_b(0){ } Base(int a, int b): m_a(a), m_b(b){ } private: int m_a; int m_b; }; int main(){ int a = 10; int b = a; //拷贝 Base ob

ccc369639963的博客 3440

类和对象【三】析构函数和拷贝构造函数

析构函数(destructor) 与构造函数相反,当对象结束其生命周期,如对象所在的函数已调用完毕时,系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如:在建立对象时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)。来自百度百科拷贝构造函数是C++中一种构造函数的重载用已有对象创建一个新对象,并将已存在的同类对象的数据成员拷贝到新对象中。拷贝构造函数的形参是一个对该已有对象的引用,并且通常会被声明为const,以防止通过引用修改原对象。

2301_80058734的博客 1524

C++拷贝构造函数(深拷贝,浅拷贝)

 转自:本Blog停止更新,感谢原作者C++拷贝构造函数(深拷贝,浅拷贝) 对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。下面看一个类对象拷贝的简单例子。 #include iostream>using namespace std;class CExample {pr

Sugar_Tiger[糖伯虎]的专栏 5930

C++拷贝构造函数详解

在C++中,拷贝构造函数是一种特殊的构造函数,用于创建一个新对象,并将其初始化为现有对象的副本。拷贝构造函数的函数名必须与类名相同,并且参数为该类的一个常引用。拷贝构造函数是一种特殊的构造函数,用于创建对象的副本。他接受一个同类型的对象(本类对象的引用)作为参数,并使用该对象的数据来初始化新对象。拷贝构造函数通常用于在程序中复制对象,以便在不修改原始对象的情况下对其进行操作。拷贝构造函数通常会执行深拷贝操作,即复制指针指向的数据,而不是仅仅复制指针本身。

m0_62573214的博客 4073
上一篇: 【c++】const加在函数的作用
下一篇: 【c++】const的作用
學602
博客等级 码龄2年 8粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值