MST

星途 面试题库

面试题:C++按值传递时参数复制过程中的浅拷贝问题

在C++中,假设有一个自定义类MyClass,包含一个动态分配的数组成员变量。当通过按值传递一个MyClass对象时,描述默认的参数复制过程,并说明可能出现的浅拷贝问题。请给出代码示例,并解释如何解决浅拷贝问题。
41.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

默认参数复制过程

当通过按值传递MyClass对象时,C++会使用默认的拷贝构造函数。默认拷贝构造函数执行的是浅拷贝,即逐个成员进行简单的值复制。

浅拷贝问题

对于包含动态分配数组成员变量的类,浅拷贝会导致多个对象的数组成员变量指向同一块内存。当其中一个对象销毁时,释放了这块内存,其他对象的数组成员变量就成了悬空指针,再次访问会导致未定义行为。

代码示例

#include <iostream>
#include <cstring>

class MyClass {
private:
    int* data;
    int size;
public:
    MyClass(int s) : size(s) {
        data = new int[size];
        std::memset(data, 0, size * sizeof(int));
    }

    ~MyClass() {
        delete[] data;
    }

    // 默认拷贝构造函数(浅拷贝)
    // MyClass(const MyClass& other) : data(other.data), size(other.size) {}

    // 自定义拷贝构造函数(深拷贝)
    MyClass(const MyClass& other) : size(other.size) {
        data = new int[size];
        std::memcpy(data, other.data, size * sizeof(int));
    }

    // 自定义赋值运算符重载(深拷贝)
    MyClass& operator=(const MyClass& other) {
        if (this != &other) {
            delete[] data;
            size = other.size;
            data = new int[size];
            std::memcpy(data, other.data, size * sizeof(int));
        }
        return *this;
    }
};

void function(MyClass obj) {
    // 这里按值传递obj
}

int main() {
    MyClass obj1(5);
    function(obj1);
    return 0;
}

解决浅拷贝问题

  1. 自定义拷贝构造函数:实现深拷贝,为新对象分配独立的内存,并将源对象的数据复制到新分配的内存中。
  2. 自定义赋值运算符重载:在赋值操作时,同样进行深拷贝,防止自赋值,并正确释放旧内存。

通过上述方式,可以确保每个MyClass对象都有自己独立的动态分配内存,避免浅拷贝带来的悬空指针等问题。