当前位置:首页 C++ > 正文

c++深拷贝和浅拷贝的区别

作者:野牛程序员:2023-07-15 12:23:39 C++阅读 3961

在C++中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是两种不同的对象拷贝方式,它们有以下区别:

  1. 浅拷贝: 浅拷贝是指在进行对象拷贝时,只复制对象中的成员变量的值,而不复制指向动态分配内存的指针。这意味着原始对象和拷贝对象将共享相同的内存资源。当一个对象的析构函数被调用时,可能会导致两个对象同时释放同一块内存,这样会导致内存错误。

  2. 深拷贝: 深拷贝是指在进行对象拷贝时,不仅复制对象中的成员变量的值,还要复制指向动态分配内存的指针所指向的实际数据。这样,原始对象和拷贝对象将拥有各自独立的内存资源,彼此之间不会相互影响。

为了实现深拷贝,通常需要自定义拷贝构造函数和赋值运算符重载函数。在这些函数中,必须显式地分配内存,并将原始对象中的数据复制到新分配的内存中。

深拷贝的优点是可以避免因为共享内存资源而引起的错误。然而,深拷贝可能会导致拷贝操作的开销增加,特别是在拷贝大型对象或对象包含大量动态分配的内存时。

总结:深拷贝会创建一个新的对象,包括复制所有的数据和动态分配的内存,而浅拷贝只是简单地复制数据的引用,共享相同的内存资源。因此,深拷贝比浅拷贝更安全,但可能会有更高的开销。选择使用深拷贝还是浅拷贝取决于具体的需求和设计。


我们可以通过一个示例来说明深拷贝和浅拷贝的区别。

假设我们有一个包含动态分配内存的类Person,它有一个字符串成员变量name,并且实现了拷贝构造函数和析构函数。下面是一个简化的示例代码:

#include <iostream>
#include <cstring>

class Person {
private:
    char* name;

public:
    // 构造函数
    Person(const char* n) {
        name = new char[strlen(n) + 1];
        strcpy(name, n);
    }

    // 拷贝构造函数
    Person(const Person& other) {
        name = new char[strlen(other.name) + 1];
        strcpy(name, other.name);
    }

    // 析构函数
    ~Person() {
        delete[] name;
    }

    // 获取姓名
    const char* getName() const {
        return name;
    }
};

现在,我们创建一个原始对象person1,并将其姓名设置为"John":

Person person1("John");

接下来,我们创建一个拷贝对象person2,并使用浅拷贝进行初始化:

Person person2 = person1; // 使用浅拷贝

此时,person1person2共享相同的内存资源,即它们的name指针指向相同的内存位置。

现在,让我们修改person2的姓名为"Mike":

person2.setName("Mike");

由于浅拷贝,person2的姓名实际上是修改了person1的姓名,因为它们共享相同的内存资源。

现在,如果我们打印person1person2的姓名,将会得到相同的结果:

std::cout << "person1: " << person1.getName() << std::endl; // 输出:person1: Mike
std::cout << "person2: " << person2.getName() << std::endl; // 输出:person2: Mike

这就是浅拷贝的效果,修改一个对象的数据会影响到另一个对象。

现在,让我们使用深拷贝来创建一个新的对象person3

Person person3(person1); // 使用深拷贝

在深拷贝的情况下,person3将有自己独立的内存资源,与person1person2完全隔离。因此,对person3的修改不会影响到其他对象。

现在,如果我们修改person3的姓名为"Alice":

person3.setName("Alice");

打印person1person2person3的姓名:

std::cout << "person1: " << person1.getName() << std::endl; // 输出:person1: Mike
std::cout << "person2: " << person2.getName() << std::endl; // 输出:person2: Mike
std::cout << "person3: " << person3.getName() << std::endl; // 输出:person3: Alice

可以看到,对person3的修改不会影响到person1person2,它们各自拥有独立的内存资源。

这就是深拷贝和浅拷贝在对象拷贝中的区别。


野牛程序员教少儿编程与信息学奥赛-微信|电话:15892516892
野牛程序员教少儿编程与信息学竞赛-微信|电话:15892516892
相关推荐

最新推荐

热门点击