【C++】浅拷贝与深拷贝

在C++中,浅拷贝(Shallow Copy)和深拷贝(Deep Copy)是两种不同的对象拷贝方式。它们之间的主要区别在于对指针成员的处理方式:

浅拷贝(Shallow Copy)

  • 浅拷贝在C++中通常是指默认的拷贝构造函数和赋值操作符。
  • 浅拷贝只复制对象中的基本数据类型的值,而不复制指向动态分配内存(如堆上分配的内存)的指针所指向的内容。换句话说,浅拷贝只复制指针的值(即内存地址),而不复制指针所指向的实际数据。
#include <iostream>
#include <cstring>

class Shallow {
public:
    char* data;
    
    Shallow(const char* value) {
        data = new char[strlen(value) + 1];
        strcpy(data, value);
    }

    // 默认的拷贝构造函数
    Shallow(const Shallow& other) = default;
    
    ~Shallow() {
        delete[] data;
    }

    void print() {
        std::cout << "Data: " << data << std::endl;
    }
};

int main() {
    Shallow original("Hello");
    Shallow copy = original;  // 使用默认拷贝构造函数进行浅拷贝

    copy.data[0] = 'h';  // 修改拷贝对象的数据
    original.print();    // 输出: "Data: hello",原始对象受到影响
    copy.print();        // 输出: "Data: hello"

    return 0;
}

在上述例子中,Shallow类的默认拷贝构造函数执行浅拷贝,使得copy对象和original对象共享同一个data指针。因此,修改copy对象的数据也会影响到original对象的数据。

深拷贝(Deep Copy)

  • 深拷贝需要显式地定义拷贝构造函数和赋值操作符,以确保在复制对象时也复制所有动态分配的内存或其他资源。
  • 深拷贝不仅复制对象中的基本数据类型的值,还复制指向动态分配内存的指针所指向的实际数据。也就是说,深拷贝为指针成员分配新的内存并复制内容,从而使新旧对象相互独立。
#include <iostream>
#include <cstring>

class Deep {
public:
    char* data;
    
    Deep(const char* value) {
        data = new char[strlen(value) + 1];
        strcpy(data, value);
    }

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

    // 深拷贝赋值操作符
    Deep& operator=(const Deep& other) {
        if (this != &other) {
            delete[] data;  // 释放已有资源
            data = new char[strlen(other.data) + 1];
            strcpy(data, other.data);
        }
        return *this;
    }
    
    ~Deep() {
        delete[] data;
    }

    void print() {
        std::cout << "Data: " << data << std::endl;
    }
};

int main() {
    Deep original("Hello");
    Deep copy = original;  // 使用深拷贝构造函数

    copy.data[0] = 'h';  // 修改拷贝对象的数据
    original.print();    // 输出: "Data: Hello",原始对象不受影响
    copy.print();        // 输出: "Data: hello"

    return 0;
}

在上述例子中,Deep类的深拷贝构造函数和赋值操作符创建了一个完全独立的副本。修改copy对象的数据不会影响original对象的数据,因为它们各自拥有独立的data内存。

总结

  • 浅拷贝:默认拷贝构造函数和赋值操作符进行逐成员的浅拷贝,可能导致多个对象共享同一块动态分配的内存,容易引起悬空指针等问题。
  • 深拷贝:显式定义拷贝构造函数和赋值操作符,确保复制对象时也复制动态分配的内存或其他资源,从而创建完全独立的副本。

在实际应用中,需要根据具体情况选择使用浅拷贝或深拷贝。如果对象包含指向动态分配内存的指针,一般建议使用深拷贝以避免内存管理问题。

相关推荐

  1. C++】拷贝拷贝

    2024-06-06 02:00:02       9 阅读
  2. c++拷贝拷贝

    2024-06-06 02:00:02       9 阅读
  3. 拷贝拷贝

    2024-06-06 02:00:02       20 阅读
  4. 拷贝拷贝

    2024-06-06 02:00:02       16 阅读
  5. 拷贝拷贝

    2024-06-06 02:00:02       8 阅读
  6. C++拷贝拷贝的区别

    2024-06-06 02:00:02       11 阅读
  7. js的拷贝拷贝

    2024-06-06 02:00:02       26 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-06 02:00:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-06 02:00:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-06 02:00:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-06 02:00:02       20 阅读

热门阅读

  1. Leetcode 297. Serialize and Deserialize Binary Tree

    2024-06-06 02:00:02       7 阅读
  2. 视觉SLAM

    2024-06-06 02:00:02       8 阅读
  3. 003 Spring注解

    2024-06-06 02:00:02       7 阅读
  4. nuxt3 api如何透传(不引第3方库)

    2024-06-06 02:00:02       9 阅读
  5. Lisp解析器技术文档

    2024-06-06 02:00:02       7 阅读
  6. Django 默认 CSRF 保护机制

    2024-06-06 02:00:02       8 阅读
  7. C语言编译与链接

    2024-06-06 02:00:02       9 阅读
  8. 设计模式(简要,应付软考)

    2024-06-06 02:00:02       7 阅读
  9. 概率图模型在自然语言处理中的应用

    2024-06-06 02:00:02       6 阅读
  10. AWS与SAP扩大战略合作:通过AI增强ERP解决方案

    2024-06-06 02:00:02       9 阅读