浅拷贝(Shallow Copy):
- 浅拷贝只复制对象的基本数据类型的成员变量,而不复制动态分配的内存或其他对象的引用。
- 当进行浅拷贝时,被拷贝对象和拷贝后的对象共享同一块内存空间,其中包括指针指向的动态内存地址。
- 如果对象内含有指针指向堆内存的地址,那么浅拷贝会导致两个对象共享同一块堆内存,这样容易出现潜在的问题,例如在释放内存时出现重复释放或野指针问题。
#include <iostream>
using namespace std;
// 定义一个名为 demo 的类
class demo
{
private:
int a; // 私有成员变量 a
int b; // 私有成员变量 b
public:
// 构造函数,初始化对象的成员变量 a 和 b
demo(int a, int b)
{
this->a = a; // 使用 this 指针来访问当前对象的成员变量 a
this->b = b; // 使用 this 指针来访问当前对象的成员变量 b
}
// 拷贝构造函数,用于创建对象的副本
demo(demo& d)
{
a = d.a; // 复制对象 d 的成员变量 a 的值
b = d.b; // 复制对象 d 的成员变量 b 的值
}
// 友元函数,用于重载输出运算符 <<
friend ostream& operator <<(ostream& cout, demo& d);
};
// 重载输出运算符 <<
ostream& operator <<(ostream& cout, demo& d)
{
cout << "a:" << d.a << " " << "b:" << d.b << endl; // 输出对象的成员变量 a 和 b
return cout; // 返回输出流对象
}
int main()
{
demo d1(10, 20); // 创建一个 demo 对象 d1,传入参数 10 和 20
demo d2(d1); // 使用拷贝构造函数创建一个 demo 对象 d2,初始化为 d1 的副本
demo *d3 = new demo(d2); // 使用拷贝构造函数创建一个 demo 对象,并在堆上分配内存,初始化为 d2 的副本
cout << d1; // 输出对象 d1 的成员变量 a 和 b
cout << d2; // 输出对象 d2 的成员变量 a 和 b
cout << *d3; // 输出指针指向的对象的成员变量 a 和 b
system("pause"); // 暂停程序运行,等待用户输入任意键后结束程序
return 0; // 返回程序执行状态
}
深拷贝(Deep Copy):
- 深拷贝会复制对象的所有数据,包括基本数据类型的成员变量以及动态分配的内存或其他对象的引用。
- 当进行深拷贝时,被拷贝对象和拷贝后的对象拥有各自独立的内存空间,即使对象内含有指针指向堆内存的地址,也会复制该地址指向的数据,使得两个对象之间完全独立,修改其中一个对象不会影响另一个对象。
在 C++ 中,对于自定义的类,如果不显式地定义拷贝构造函数和拷贝赋值运算符,编译器会自动生成默认的浅拷贝版本。如果类中存在指针成员,使用默认的浅拷贝可能会导致意外的行为,这时就需要自定义深拷贝的函数来确保对象的完整性和安全性。
总的来说,浅拷贝适用于对象内部没有动态内存分配或不需要独立拷贝的情况,而深拷贝适用于对象内部包含有指针指向动态内存分配的情况,需要确保拷贝后的对象与原对象完全独立。