0
点赞
收藏
分享

微信扫一扫

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

梦为马 2024-06-07 阅读 15

在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内存。

总结

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

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

举报

相关推荐

0 条评论