Skip to content

浅拷贝与深拷贝

浅拷贝就是

1.浅拷贝

下面代码可以看出,Person中有个变量pet存放在堆中,使用拷贝函数把一个对象的构造函数拷贝过去,

发现修改age不影响,别的对象,而修改pet中的数据,另一个对象中的数据也会被影响

这是因为当拷贝一个构造函数时,在栈上的数据全拷贝过去,而堆上的数据拷贝的却是堆地址

c++
#include<iostream>
using namespace std;

class Pet {
public:
	string name;
};

class Person {
public:
	int age;
	Pet* pet;
	Person() {
		age = 0;
		pet = new Pet();
	}
	Person(const Person& p) {
		age = p.age;
		pet = p.pet;
	}
};

int main() {
	Person p1;
	Person p2 = Person(p1);

	p1.age = 18;
	cout << p1.age << endl;			// 18
	cout << p2.age << endl;			// 0

	p1.pet->name = "小猫";
	cout << p1.pet->name << endl;		// 小猫
	cout << p2.pet->name << endl;		// 小猫
	return 0;
}

TIP

因为浅拷贝是吧栈中的数据拷贝过去,而pet在栈中存放的是堆地址,所以两个对象中的pet是同一个image-20240719103330594

2.深拷贝

深拷贝则是当实现构造函数拷贝时,不直接拷贝数据的堆地址,而是从新创建一个堆数据,把堆中的数据一一拷贝过去,并且在析构函数中把堆中数据清空

c++
#include<iostream>
using namespace std;

class Pet {
public:
	string name;
};

class Person {
public:
	int age;
	Pet* pet;
	Person() {
		age = 0;
		pet = new Pet();
	}
	Person(const Person& p) {
		age = p.age;
		// pet = p.pet;
		pet = new Pet();
		pet->name = p.pet->name;
	}
	~Person() {
		if (pet != nullptr) {
			delete pet;
			pet = nullptr;
		}
	}
};

int main() {
	Person p1;
	Person p2 = Person(p1);

	p1.age = 18;
	cout << p1.age << endl;			// 18
	cout << p2.age << endl;			// 0

	p1.pet->name = "小猫";
	cout << p1.pet->name << endl;		// 小猫
	cout << p2.pet->name << endl;		// 
	return 0;
}

MIT Licensed