浅复制和深复制
题目描述
当一个类的成员变量含有指针时,如果采用默认复制构造函数进行复制,会导致两者指向同一片内存空间,从而导致对其中一个对象指针进行操作会体现在另一对象上。
当成员中含有指针时,朴素地把指针当成普通变量一样直接复制,我们称这种复制方法为“浅复制”。为了解决这一问题,我们可以重新定义复制构造函数,实现“深复制”,请补全下列代码,使得输出符合要求,并思考浅复制和深复制的区别和联系。
关于输入
无
关于输出
见样例输出
核心技巧
- 当成员变量涉及指针类型时,不能简单地通过指针变量赋值的方式进行复制。
- 为解决这一问题,可以通过在复制构造时在复制目标对象重新开辟内存空间,将内容复制过来。
参考答案
#include <iostream>
#include <cstring>
#include <cassert>
using std::cout, std::endl;
class String {
public:
char* str;
int len;
String(const char* s){
len = strlen(s);
str = new char[len + 1];
strcpy(str, s);
}
String(const String& s){
len = s.len;
str = new char[len + 1];
strcpy(str, s.str);
}
~String(){
delete[] str;
}
};
void pass_by_ref(String& s){
s.str[0] = 'B';
}
void pass_by_val(String s){
s.str[0] = 'B';
}
// 内存分配计数器
int allocCount{0};
int main(){
{
String str1("Dog");
const String str2("Dog");
pass_by_ref(str1);
pass_by_val(str2);
cout << str1.len << " " << str1.str << endl;
cout << str2.len << " " << str2.str << endl;
}
assert(allocCount == 0);
}
// 下列代码用于确保你的代码未发生内存泄漏,不用深究
void* operator new[](std::size_t size) {
if (void* ptr = std::malloc(size)) { allocCount++; return ptr; }
throw std::bad_alloc{};
}
void operator delete[](void* ptr) {
allocCount--;
std::free(ptr);
}