面试题答案
一键面试默认参数复制过程
当通过按值传递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;
}
解决浅拷贝问题
- 自定义拷贝构造函数:实现深拷贝,为新对象分配独立的内存,并将源对象的数据复制到新分配的内存中。
- 自定义赋值运算符重载:在赋值操作时,同样进行深拷贝,防止自赋值,并正确释放旧内存。
通过上述方式,可以确保每个MyClass
对象都有自己独立的动态分配内存,避免浅拷贝带来的悬空指针等问题。