💓 博客主页:倔强的石头的CSDN主页
📝Gitee主页:倔强的石头的gitee主页
⏩ 文章专栏:《C++指南》
期待您的关注
目录
引言
🍃浅拷贝
基本概念
代码示例分析
🍃深拷贝
基本概念
代码示例分析
总结
引言
在C++中,对象的复制是一个非常重要的概念,它涉及到资源管理和内存安全。当一个对象被复制时,根据对象内部数据成员的复制方式不同,可以分为浅拷贝(Shallow Copy)和深拷贝(Deep Copy)两种类型。
理解这两种复制的区别对于避免程序中的潜在错误至关重要。
本文将详细剖析这两个概念,并通过示例代码加以说明。
🍃浅拷贝
基本概念
- 浅拷贝是指在复制对象时,仅仅复制对象的所有非静态成员变量的值。
- 如果这些成员变量是基本数据类型,那么它们的值会被直接复制到新对象中;
- 如果是指针或引用类型,则只会复制指针或引用本身,而不会复制指针指向的数据。这意味着两个对象将共享同一份数据。
代码示例分析
//浅拷贝
#include <iostream>
using namespace std;
class ShallowCopy {
private:
int* data;
public:
ShallowCopy(int d) : data(new int(d)) {} // 构造函数
~ShallowCopy() { delete data; } // 析构函数
void setData(int d) { *data = d; }
int getData() const { return *data; }
// 默认复制构造函数(浅拷贝)
ShallowCopy(const ShallowCopy& source) : data(source.data) {}
};
int main() {
ShallowCopy obj1(10);
ShallowCopy obj2 = obj1; // 使用默认复制构造函数
cout << "obj1 data: " << obj1.getData() << endl;
cout << "obj2 data: " << obj2.getData() << endl;
obj1.setData(20); // 修改 obj1 的数据
cout << "After modifying obj1" << endl;
cout << "obj1 data: " << obj1.getData() << endl;
cout << "obj2 data: " << obj2.getData() << endl; // obj2 数据也被修改了
return 0;
}
分析:
在这个例子中,obj1
和 obj2
都指向同一个整数。因此,当 obj1
的数据改变时,obj2
的数据也随之改变。这展示了浅拷贝的一个主要缺点:两个对象之间存在数据依赖,可能导致不可预见的行为。
🍃深拷贝
基本概念
- 深拷贝则是创建一个全新的对象,并且这个新对象与原对象完全独立。
- 对于每个指针成员,深拷贝会分配新的内存空间来存储一份完全相同的数据副本。这样,即使原始对象的数据发生变化,也不会影响到复制的对象。
代码示例分析
//深拷贝
#include <iostream>
using namespace std;
class DeepCopy {
private:
int *data;
public:
DeepCopy(int d) : data(new int(d)) {} // 构造函数
~DeepCopy() { delete data; } // 析构函数
void setData(int d) { *data = d; }
int getData() const { return *data; }
// 自定义复制构造函数(深拷贝)
DeepCopy(const DeepCopy &source) : data(new int(*source.data)) {}
};
int main() {
DeepCopy obj1(10);
DeepCopy obj2 = obj1; // 使用自定义复制构造函数
cout << "obj1 data: " << obj1.getData() << endl;
cout << "obj2 data: " << obj2.getData() << endl;
obj1.setData(20); // 修改 obj1 的数据
cout << "After modifying obj1" << endl;
cout << "obj1 data: " << obj1.getData() << endl;
cout << "obj2 data: " << obj2.getData() << endl; // obj2 数据没有变化
return 0;
}
分析:
这里,obj2
是通过深拷贝从 obj1
创建的。因此,obj1
和 obj2
各自拥有独立的数据副本。当 obj1
的数据被修改后,obj2
的数据保持不变,体现了深拷贝的优势——对象之间的数据独立性。
总结
- 浅拷贝:简单复制成员变量的值,对于指针成员变量,只是复制指针值,两个对象共享同一块内存。快速简单,但在处理动态分配的资源时可能会导致数据不一致或内存泄漏等问题。
- 深拷贝:为成员变量分配新的内存空间,并复制原对象的成员变量的值到新对象的对应成员变量中,两个对象拥有独立的内存空间。虽然需要更多的系统资源和时间来完成复制过程,但它能确保两个对象之间的完全独立,避免了共享数据带来的风险。
了解并正确使用浅拷贝与深拷贝,对于避免资源泄漏、数据损坏和潜在的内存管理错误至关重要。选择使用浅拷贝还是深拷贝取决于具体的应用场景。如果对象间不需要完全独立,且性能是关键考虑因素,可以选择浅拷贝。反之,若对象间必须保持独立,尤其是当对象包含动态分配的资源时,应使用深拷贝。