一、C++中的浅拷贝和深拷贝
1、浅拷贝:只是复制了某个对象的指针,也就是说复制后的对象与原始对象共享同一块内存空间,对其中一个对象进行修改会影响到另一个对象。浅拷贝通常是使用默认的构造函数和赋值运算符实现的。
2、深拷贝:会创建一个新的对象,值与原始对象一模一样,但是二者不会贡献同一块内存空间,彼此之间的修改互不影响。深拷贝需要自定义的复制构造函数、赋值操作符来实现,即需要手动开辟一块新的内存空间。
3、总结:C++中,浅拷贝不需要自己实现,编译器会自动生成缺省的拷贝构造函数,浅拷贝新旧对象共享一块内存,任何一方的值改变都会影响另一方;深拷贝需要自己手动编写拷贝构造函数,深拷贝新旧对象不共享内存。
#include <iostream>
class Person {
private:
int age;
int* ptr;
public:
Person(int age, int data) {
this->age = age;
ptr = new int(data);
}
// 浅拷贝的复制构造函数
Person(const Person& other) {
age = other.age;
ptr = other.ptr;
}
// 深拷贝的复制构造函数
// Person(const Person& other) {
// age = other.age; // age与指针无关,因此不涉及浅拷贝和深拷贝
// ptr = new int(*(other.ptr));
// }
~Person() {
delete ptr;
}
void display() {
std::cout << "Age: " << age << ", Data: " << *ptr << std::endl;
}
};
int main() {
Person p1(25, 100);
Person p2 = p1; // 进行对象赋值或复制
p1.display();
p2.display();
// 修改 p1 的数据
*(p1.ptr) = 200;
p1.display();
p2.display(); // 浅拷贝时会影响到 p2 的数据,深拷贝则不受影响
return 0;
}
二、Python中的赋值运算符"=",浅拷贝copy()以及深拷贝deepcopy()
- 首先介绍一下C++和Python中 引用 的区别
C++:引用是变量的别名,不存在空引用,使用&创建引用。引用必须在定义时初始化,并且一旦初始化后,它将始终引用同一个对象,无法被重新赋值为引用其他对象。
Python:引用更像是指针,表示的是内存地址,例如赋值/浅拷贝过程中,会将引用传递给新变量。
1、赋值运算符 “=”
- 赋值运算符将一个对象的引用(内存地址)复制给另一个变量,使得两个变量指向同一个内存地址。这意味着对其中一个变量进行修改会影响到另一个变量。
但是,尤其需要注意的是,对于不可变对象(如整数、字符串等),赋值后,两个变量的修改是互相不影响的。
- 例如,对于列表:
original_list = [1, 2, 3]
new_list = original_list # 使用赋值运算符进行赋值
new_list.append(4)
print(original_list) # 输出 [1, 2, 3, 4]
- 但是对于整数:由于整数是不可变对象,所以对 a 进行修改实际上是创建了一个新的整数对象,并将其赋给 a。因此,b 仍然持有原始的整数对象的引用,其值并未改变。
a = 10 # 创建一个整数对象
b = a # 使用赋值运算符将 a 的值赋给 b
a = 20 # 修改 a 的值
print(b) # 输出 10,b 的值没有改变
2、浅拷贝copy()
- 浅拷贝是对原始对象的顶层引用。换句话说,它复制了原始对象,但对于嵌套对象(如列表中的列表或字典中的字典),仍然共享相同的引用。
- 因此,对于嵌套对象,如果进行其中一个变量的修改,另一个变量也会发生改变。
- 但是,对非嵌套的对象,由于copy()创建了新对象,因此二者的修改互不影响。
import copy
original_list = [1, 2, [3, 4]]
shallow_copy = copy.copy(original_list)
# 非嵌套的对象的修改
original_list[1] = 20
print(shallow_copy) # [1, 2, [3, 4]]
print(original_list) # [1, 20, [3, 4]]
# 嵌套的对象的修改
original_list[2][0] = 5
print(shallow_copy) # 输出 [1, 2, [5, 4]]
print(original_list) # [1, 20, [5, 4]]
3、深拷贝deepcopy()
- 深拷贝会创建一个新对象,并递归复制原始对象及其所有嵌套对象。这意味着深拷贝的副本是完全独立的,对原始对象或其嵌套对象的任何修改都不会影响深拷贝的副本。
- 例如:
import copy
original_list = [1, 2, [3, 4]]
deep_copy = copy.deepcopy(original_list)
# 非嵌套的对象的修改
original_list[1] = 20
print(deep_copy) # [1, 2, [3, 4]]
print(original_list) # [1, 20, [3, 4]]
# 嵌套的对象的修改
original_list[2][0] = 5
print(deep_copy) # 输出 [1, 2, [3, 4]]
print(original_list) # [1, 20, [5, 4]]