C++中的浅拷贝和深拷贝的区别
admin
2023-07-30 20:15:38
0

一般来说,创建一个对象的副本意味着创建一个具有相同字面价值、数据类型和资源的对象的精确副本。

  • 复制构造器
  • 默认的赋值运算符
// Copy Constructor
Object Obj1(Obj);
或者
Object Obj1 = Obj;

// Default assignment operator
Object Obj2;
Obj2 = Obj1;

根据对象所拥有的动态内存等资源,我们需要执行Shallow Copy或Deep Copy,以创建对象的副本。一般来说,如果一个对象的变量是动态分配的,那么就需要进行深度拷贝,以便创建一个对象的副本。

浅拷贝

在浅层拷贝中,通过简单地复制原始对象的所有变量的数据来创建一个对象。如果对象的变量都没有定义在内存的堆区,那么这个方法很好用。如果一些变量是从堆区动态分配的内存,那么复制的对象变量也将引用相同的内存位置。
这将产生模糊性和运行时错误,即悬空指针。由于两个对象都会引用相同的内存位置,那么一个对象的变化也会反映在另一个对象上。由于我们想要创建一个对象的副本,这个目的将不会被Shallow copy所填补。

注意:C++编译器隐含地创建了一个复制构造函数和重载赋值运算符,以便在编译时执行浅层复制。

示例代码:

// C++ program for the above approach
#include 
using namespace std;

// Box Class
class box {
private:
    int length;
    int breadth;
    int height;

public:
    // Function that sets the dimensions
    void set_dimensions(int length1, int breadth1,int height1)
    {
        length = length1;
        breadth = breadth1;
        height = height1;
    }

    void show_data()
    {
        cout << " Length = " << length
            << " Breadth = " << breadth
            << " Height = " << height
            << endl;
    }
};

// Driver Code
int main()
{
    // Object of class Box
    box B1, B3;

    // Set dimensions of Box B1
    B1.set_dimensions(214, 212, 216);
    B1.show_data();

    box B2 = B1;
    B2.show_data();

    B3 = B1;
    B3.show_data();

    return 0;
}

运行结果:

Length = 214
Breadth = 212
Height = 216
Length = 214
Breadth = 212
Height = 216
Length = 214
Breadth = 212
Height = 216

深复制

在深度复制中,通过复制所有变量的数据来创建一个对象,同时也为该对象分配相同价的类似内存资源。为了执行深度复制,我们需要明确地定义复制构造函数,如果需要的话,还需要分配动态内存。此外,还需要为其他构造函数中的变量动态分配内存。

示例代码:

#include 
using namespace std;

// Box Class
class box {
private:
    int length;
    int* breadth;
    int height;

public:
    // Constructor
    box()
    {
        breadth = new int;
    }

    void set_dimension(int len, int brea,
                    int heig)
    {
        length = len;
        *breadth = brea;
        height = heig;
    }

    // Function to show the dimensions
    // of the Box
    void show_data()
    {
        cout << "Length = " << length
            << "Breadth = " << *breadth
            << "Height = " << height
            << endl;
    }

    // Parameterized Constructors for
    // for implementing deep copy
    box(box& sample)
    {
        length = sample.length;
        breadth = new int;
        *breadth = *(sample.breadth);
        height = sample.height;
    }

    // Destructors
    ~box()
    {
        delete breadth;
    }
};

// Driver Code
int main()
{
    // Object of class first
    box first;

    // Set the dimensions
    first.set_dimension(212, 214, 216);

    // Display the dimensions
    first.show_data();

    box second = first;

    // Display the dimensions
    second.show_data();

    return 0;
}

运行结果:

Length = 212
Breadth = 214
Height = 216
Length = 212
Breadth = 214
Height = 216

让我们以表格的形式来看看其中的区别:

浅拷贝 深拷贝
1 当通过拷贝所有成员变量的数据来创建一个对象的副本时,它被称为浅度复制。 当通过复制另一个对象的数据以及位于该对象之外的内存资源的值来创建一个对象时,它被称为深度复制。
2 一个对象的浅拷贝复制了所有的成员字段值。 深拷贝是通过实现自己的拷贝构造函数来进行的。
3 在浅层拷贝中,两个对象不是独立的 它拷贝所有字段,并拷贝字段所指向的动态分配的内存
4 浅拷贝还创建了动态分配对象的副本 如果没有以正确的方式创建深度拷贝,那么副本将指向原始对象,这将带来灾难性的后果。

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
项目管理和工程管理的区别 项目管理 项目管理,顾名思义就是专注于开发和完成项目的管理,以实现目标并满足成功标准和项目要求。 工...