拷贝函数解释

拷贝构造函数
拷贝构造函数,经常被称作X(X&),是一种特殊的构造函数,
他由编译器调用来完成一些基于同一类的其他对象的构件及初始化。
它的唯一的一个参数(对象的引用)是不可变的(因为是const型的)。
这个函数经常用在函数调用期间于用户定义类型的值传递及返回。
拷贝构造函数要调用基类的拷贝构造函数和成员函数。如果可以的话,它将用常量方式调用,
另外,也可以用非常量方式调用。
  在C++中,下面三种对象需要拷贝的情况。因此,拷贝构造函数将会被调用,并且会创建对象。
  1). 一个对象以值传递的方式传入函数体
  2). 一个对象以值传递的方式从函数返回
  3). 一个对象需要通过另外一个对象进行初始化
  以上的情况需要拷贝构造函数的调用。如果在前两种情况不使用拷贝构造函数的时候,
就会导致一个指针指向已经被删除的内存空间。对于第三种情况来说,初始化和赋值的不同含
义是构造函数调用的原因。事实上,拷贝构造函数是由普通构造函数和赋值操作赋共同实现的。
描述拷贝构造函数和赋值运算符的异同的参考资料有很多。
  拷贝构造函数不可以改变它所引用的对象,其原因如下:当一个对象以传递值的方式传一个函数的时候,
拷贝构造函数自动的被调用来生成函数中的对象。如果一个对象是被传入自己的拷贝构造函数,
它的拷贝构造函数将会被调用来拷贝这个对象这样复制才可以传入它自己的拷贝构造函数,这会导致无限循环。
  除了当对象传入函数的时候被隐式调用以外,拷贝构造函数在对象被函数返回的时候也同样的被调用。
换句话说,你从函数返回得到的只是对象的一份拷贝。但是同样的,拷贝构造函数被正确的调用了,你不必担心。
  如果在类中没有显式的声明一个拷贝构造函数,
那么,编译器会私下里为你制定一个函数来进行对象之间的位拷贝(bitwise copy)。
这个隐含的拷贝构造函数简单的关联了所有的类成员。许多作者都会提及这个默认的拷贝构造函数。
注意到这个隐式的拷贝构造函数和显式声明的拷贝构造函数的不同在于对于成员的关联方式。
显式声明的拷贝构造函数关联的只是被实例化的类成员的缺省构造函数除非另外一个构造函数在类初始化或者
在构造列表的时候被调用。
  拷贝构造函数是程序更加有效率,因为它不用再构造一个对象的时候改变构造函数的参数列表。
设计拷贝构造函数是一个良好的风格,即使是编译系统提供的帮助你申请内存默认拷贝构造函数。
事实上,默认拷贝构造函数可以应付许多情况。
在编程中,**拷贝函数**(Copy Function)通常指的是用于创建一个对象的副本的函数或方法。这个概念在不同的编程语言中有不同的实现方式和术语,比如在 C++ 中称为“拷贝构造函数”或“赋值运算符”,而在 Python 等高级语言中可能通过内置函数或自定义方法实现。 拷贝的核心目的是:**避免原始数据被意外修改**,或者在需要独立操作数据副本时使用。 根据拷贝的深度不同,主要分为两种类型: --- ### 1. 浅拷贝(Shallow Copy) - 只复制对象本身,但对象内部引用的子对象仍然共享。 - 修改副本中的嵌套对象会影响原对象。 ### 2. 深拷贝(Deep Copy) - 完全复制整个对象及其所有子对象,形成一个完全独立的新对象。 - 原对象和副本互不影响。 --- ## 示例:Python 中的拷贝函数 ```python import copy # 原始列表包含嵌套结构 original = [1, 2, [3, 4]] # 浅拷贝 shallow_copied = copy.copy(original) # 深拷贝 deep_copied = copy.deepcopy(original) # 修改原始数据中的嵌套列表 original[2].append(5) print("Original:", original) # [1, 2, [3, 4, 5]] print("Shallow:", shallow_copied) # [1, 2, [3, 4, 5]] ← 被影响了! print("Deep:", deep_copied) # [1, 2, [3, 4]] ← 不受影响 ``` ### 解释: - `copy.copy()` 是浅拷贝函数,它复制了外层列表,但内层 `[3,4]` 是引用。 - `copy.deepcopy()` 是深拷贝函数,递归复制所有层级,完全独立。 - 当我们修改 `original[2].append(5)` 时,由于浅拷贝共享嵌套列表,所以 `shallow_copied` 也被改变;而深拷贝不受影响。 --- ## 自定义类中的拷贝(Python 示例) ```python class Person: def __init__(self, name, hobbies): self.name = name self.hobbies = hobbies # list 类型 def __repr__(self): return f"Person({self.name}, {self.hobbies})" p1 = Person("Alice", ["reading", "music"]) # 浅拷贝 p2 = copy.copy(p1) p2.hobbies.append("painting") print(p1) # Person(Alice, ['reading', 'music', 'painting']) ← 被影响 print(p2) # Person(Alice, ['reading', 'music', 'painting']) # 深拷贝可避免此问题 p3 = copy.deepcopy(p1) p3.hobbies.append("dancing") print(p1) # 不变 print(p3) # 新增 hobby ``` --- ## 其他语言中的拷贝函数 ### C++ 中的拷贝构造函数 ```cpp class MyClass { public: int* data; int size; // 构造函数 MyClass(int s) : size(s) { data = new int[s]; } // 拷贝构造函数(手动实现深拷贝) MyClass(const MyClass& other) : size(other.size) { data = new int[other.size]; for (int i = 0; i < size; ++i) { data[i] = other.data[i]; } } ~MyClass() { delete[] data; } }; ``` 如果不写拷贝构造函数,C++ 默认提供浅拷贝,可能导致内存错误(如重复释放同一块内存)。 --- ### JavaScript 中的拷贝 ```javascript // 浅拷贝 const obj1 = { a: 1, b: { c: 2 } }; const obj2 = { ...obj1 }; // 展开语法 const obj3 = Object.assign({}, obj1); // 深拷贝(简单情况可用 JSON,但不支持函数、undefined、Symbol 等) const obj4 = JSON.parse(JSON.stringify(obj1)); // 推荐使用 Lodash 的 _.cloneDeep 或递归实现深拷贝 ``` --- ## 总结 | 类型 | 是否复制引用对象 | 独立性 | 使用场景 | |----------|------------------|--------|-----------| | 浅拷贝 | 否(共享) | 低 | 快速复制,不涉及嵌套修改 | | 深拷贝 | 是(递归复制) | 高 | 需要完全隔离的数据操作 | 选择哪种拷贝方式取决于你的需求:是否希望副本与原对象完全独立。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值