Why delete[] array when deepcopying with “=“?-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

代码负责释放对象之前已经分配的资源比如堆上的内存。在执行深拷贝之前你需要确保对象不再引用之前的资源以避免内存泄漏。通过删除先前的资源你可以确保在进行深拷贝之前已经释放了之前的资源从而避免了资源泄漏。

当一个对象拥有动态分配的资源比如堆上的内存并且你希望将另一个对象的内容赋值给它时你需要确保在赋值之前释放已经分配的资源以避免内存泄漏。下面是一个具体的示例

假设你有一个自定义的类 IntArray它包含一个整数指针 array用于存储动态分配的整数数组以及一个整数 nElements表示数组中的元素数量。你的类如下所示

class IntArray {
private:
    int *array;
    int nElements;

public:
    // 构造函数
    IntArray(int size) {
        nElements = size;
        array = new int[size];
    }

    // 析构函数
    ~IntArray() {
        delete[] array;
    }

    // 赋值运算符重载
    IntArray &operator=(const IntArray &src) {
        if (this != &src) { // 防止无效的自我赋值
            delete[] array; // 释放现有资源
            deepCopy(src);  // 执行深拷贝
        }
        return *this;
    }

    // 深拷贝函数
    void deepCopy(const IntArray &src) {
        nElements = src.nElements;
        array = new int[nElements];
        for (int i = 0; i < nElements; ++i) {
            array[i] = src.array[i];
        }
    }

    // 其他方法和成员变量
    // ...
};

现在考虑以下情况你有两个 IntArray 对象 array1array2

IntArray array1(5); // 创建 array1分配了一个包含5个整数的数组
IntArray array2(3); // 创建 array2分配了一个包含3个整数的数组
array1 = array2; // 赋值操作

在这个赋值操作之前array1 已经拥有了一个包含5个整数的数组而 array2 拥有一个包含3个整数的数组。为了执行赋值操作你需要确保在将 array2 的内容复制到 array1 之前释放了 array1 之前分配的资源以避免内存泄漏。

这就是为什么在赋值运算符重载函数中存在 delete[] array; 这行代码的原因。它的目的是在执行深拷贝之前释放 array1 的资源然后再为 array1 分配新的资源确保 array1array2 是独立的不会导致内存泄漏。

在这段代码中src&srcthisarray 分别指代以下内容

  1. src这是函数的参数表示传递给赋值运算符重载函数的右操作数即源对象。src 是一个 const IntArray & 类型的引用表示它是一个 IntArray 类的对象的引用该对象将用于赋值操作。

  2. &src这是 src 的地址表示源对象 src 在内存中的位置。& 运算符用于获取变量或对象的地址。在这里它用于比较 thissrc 是否相同以检查是否发生了自我赋值。

  3. this这是指向当前对象的指针即调用赋值运算符重载函数的对象的指针。在这个上下文中this 表示正在执行赋值操作的目标对象即接收赋值的对象。

  4. array这是当前对象 this 中的成员变量表示整数指针用于存储动态分配的整数数组。delete[] array; 行代码用于释放当前对象 this 中的数组资源。

那为什么this对象可以跟地址比较

`this` 指针是一个指向当前对象的指针在 C++ 中它是一个隐式参数传递给成员函数以表示调用该函数的对象。因此`this` 指针可以用于在成员函数内部访问对象的成员变量和方法。

在这段代码中`this` 指针用于表示当前对象而 `&src` 用于表示传递给赋值运算符重载函数的源对象 `src` 的地址。通过比较 `this` 和 `&src`代码检查是否发生了自我赋值即是否试图将对象赋值给它自己。

如果 `this` 和 `&src` 是相同的这意味着赋值操作试图将对象赋值给它自己这是一个无效的操作可能会导致问题因此需要避免。所以通过比较 `this` 和 `&src`可以防止自我赋值情况的发生。

那为啥不是this和src比较或者this→array和&src比较

 

在 C++ 中`this` 是一个指向当前对象的指针`src` 是一个表示传递给赋值运算符重载函数的源对象的引用。它们具有不同的类型和语义因此不能直接进行比较。具体来说

1. `this` 是一个指向当前对象的指针类型为 `IntArray*`。它用于在成员函数内部访问对象的成员变量和方法。

2. `src` 是一个表示传递给赋值运算符重载函数的源对象的引用类型为 `const IntArray&`。它是一个对象的别名用于访问源对象的数据。

这两者之间的比较是没有意义的因为它们代表了不同的概念和数据类型。在自我赋值检查中我们关心的是比较当前对象和源对象是否是同一个对象。为了执行这个比较我们使用 `this` 指针和 `&src`因为它们分别表示当前对象和源对象在内存中的位置地址从而允许我们进行地址比较。

要比较对象的成员变量你需要使用成员访问运算符 `.` 来访问对象的成员变量例如 `this->array` 和 `src.array`。然而这不会执行自我赋值检查因为它只是比较成员变量的值而不是对象的身份。在自我赋值检查中我们关心的是对象的身份即对象是否相同因此需要比较它们的地址。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6