【C++和Python】浅拷贝和深拷贝的区别

一、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]]
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值