【C++】深拷贝和浅拷贝 ① ( 深拷贝与浅拷贝概念简介 | 浅拷贝与深拷贝对比 | 浅拷贝与深拷贝的使用场景 )

2023-10-15 17:07:26 浏览数 (1)

一、深拷贝与浅拷贝概念简介

1、浅拷贝

浅拷贝 :

  • 浅拷贝赋值表层成员变量 : 拷贝对象时只拷贝对象的顶层成员 , 即仅复制 对象本身 及 对象成员变量 , 不复制成员变量中的 子变量 ;
  • 成员变量是指针或引用的情况 : 如果 对象 中的成员变量是 指向其他对象的 指针 或 引用 , 拷贝该对象时 , 复制的事这些指针或引用本身 , 指针或引用仍然指向原来的内存 ;
  • 浅拷贝影响 : 使用浅拷贝将原对象复制一份后 , 对复制的对象进行修改可能会影响到原对象 ; 因为 两个 对象 持有 相同 的指针 / 引用 ;

浅拷贝场景 : 假设有一个包含 字符串成员变量 的类 , 使用浅拷贝复制该对象时 , 将复制 字符串指针 , 两个对象持有相同的指针变量值 ; 如果对复制的对象的 字符串成员变量 进行修改 , 原始对象的 字符串成员变量 也将被修改 ;

使用浅拷贝 , 就不要对 指针 / 引用 指向的内存空间进行修改操作 , 否则会导致出现各种未知问题 ;

2、深拷贝

深拷贝 :

  • 深拷贝赋值表层成员变量 : 拷贝对象时拷贝对象的 顶层成员 和 子成员 , 不仅复制 对象本身 及 对象成员变量 , 还复制成员变量中的 子变量 ;
  • 成员变量是指针或引用的情况 : 如果 对象 中的成员变量是 指向其他对象的 指针 或 引用 , 拷贝该对象时 , 不会复制的事这些指针或引用本身 , 而是复制指针或引用指向的内存数据 到 新内存空间中 , 并 重新分配一个指针指向新的内存空间 ;
  • 深拷贝影响 : 使用深拷贝将原对象复制一份后 , 对复制的对象进行修改 不会影响到原对象 ; 因为 两个 对象 持有 不同 的指针 / 引用 , 指向不同的内存空间中 ;

深拷贝场景 : 假设有一个包含 字符串成员变量 的类 , 使用深拷贝复制该对象时 , 将复制 字符串指针 指向的内存地址 , 两个对象持有 指向不同内存空间的 不同的指针 ; 如果对复制的对象的 字符串成员变量 进行修改 , 原始对象的 字符串成员变量 不会被修改 ;

3、浅拷贝与深拷贝对比

深拷贝 和 浅拷贝 之间没有优劣之分 , 二者有不同的应用场景 ;

  • 深拷贝 更加安全 , 是完整的数据拷贝 , 数据是完全的另外一个备份 , 但是相应的拷贝性能会下降 , 占用 内存 / CPU 资源更多 ;
  • 浅拷贝 缺少安全性 , 但是性能很高 , 执行效率高 ;

根据 深拷贝 和 浅拷贝 的 特点 , 以及所开发程序的应用场景 , 选择具体的拷贝方案 ;

4、浅拷贝与深拷贝的使用场景

浅拷贝 适用场景 :

  • 成员变量不是引用 / 指针 : 对象 中 的成员变量 不是其它 对象的 引用 或 指针 ;
  • 成员变量 的 引用 / 指针 类型是可拷贝的 : 对象 中 的成员变量 引用 或 指针 指向的 对象类型 可拷贝 ;
  • 拷贝构造函数简单 : 对象的 拷贝构造函数 和 拷贝赋值运算符的实现 比较简单 , 且不需要处理对象的内部子对象的拷贝时 ;
  • 拷贝对象具有独立性 : 对 拷贝对象 的修改 不会影响 原始对象 , 且不需要保证对象的独立性时 ;

深拷贝 适用场景 :

  • 成员变量是引用 / 指针 : 当对象包含其他对象的引用或指针 , 且这些引用或指针指向的对象类型不同或不可拷贝时 ;
  • 拷贝构造函数复杂 : 对象的 拷贝构造函数 和 拷贝赋值运算符的实现 需要处理 对象的内部子对象 的拷贝时 ;
  • 拷贝对象没有独立性 : 对拷贝对象的修改会影响原始对象 时 , 必须使用深拷贝 ;

0 人点赞