面试题答案
一键面试浅拷贝和深拷贝在重写拷贝构造函数时的区别
- 浅拷贝:
- 在浅拷贝中,当使用拷贝构造函数创建一个新对象时,新对象的成员变量直接复制源对象对应成员变量的值。对于指针类型的成员变量,只是复制了指针的值,即新对象和源对象的指针成员指向同一块内存地址。
- 例如:
class ShallowCopy {
public:
int *data;
ShallowCopy(int value) {
data = new int(value);
}
// 浅拷贝构造函数
ShallowCopy(const ShallowCopy& other) {
data = other.data;
}
~ShallowCopy() {
delete data;
}
};
- 深拷贝:
- 深拷贝在创建新对象时,对于指针类型的成员变量,会重新分配内存,并将源对象指针所指向内存中的内容复制到新分配的内存中。这样新对象和源对象的指针成员指向不同的内存地址,但内容相同。
- 例如:
class DeepCopy {
public:
int *data;
DeepCopy(int value) {
data = new int(value);
}
// 深拷贝构造函数
DeepCopy(const DeepCopy& other) {
data = new int(*other.data);
}
~DeepCopy() {
delete data;
}
};
使用浅拷贝导致程序错误的情况
当对象包含动态分配的内存(如上述例子中的指针 data
),并且使用浅拷贝构造函数时,会出现以下问题:
- 内存释放问题:
- 当源对象和拷贝对象都要销毁时,由于它们的指针指向同一块内存,会导致这块内存被释放两次,这是未定义行为。例如,上述
ShallowCopy
类,当两个ShallowCopy
对象都析构时,都会执行delete data
,就会出现内存二次释放错误。
- 当源对象和拷贝对象都要销毁时,由于它们的指针指向同一块内存,会导致这块内存被释放两次,这是未定义行为。例如,上述
- 数据一致性问题:
- 如果其中一个对象修改了动态分配内存中的数据,由于另一个对象的指针也指向这块内存,会导致另一个对象的数据也意外改变。例如,在
ShallowCopy
类中,如果其中一个对象修改了*data
的值,另一个对象的*data
值也会改变,这可能不符合程序的预期逻辑。
- 如果其中一个对象修改了动态分配内存中的数据,由于另一个对象的指针也指向这块内存,会导致另一个对象的数据也意外改变。例如,在