卡码笔记
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
  • 基础与语法

  • 面向对象

    • C++构造函数有几种,分别什么作用?
    • 什么是构造函数和析构函数?构造函数和析构函数可以是虚函数吗?为什么?
    • C++的重载和重写,以及它们的区别和实现方式
    • C++怎么实现多态
    • C++中的虚函数和纯虚函数有什么区别?
    • 虚函数怎么实现的?
    • 虚函数表是什么
    • 多重继承的优缺点及菱形继承问题
    • 如何禁止一个类被继承
    • 深拷贝和浅拷贝的区别?
      • 简要回答
      • 详细回答
      • 代码示例
      • 知识拓展
    • this指针的原理
    • C++如何实现一个单例模式?
  • STL 与容器

  • 内存管理

  • C++11 与现代 C++

  • 智能指针

  • 并发与 I/O

# 深拷贝和浅拷贝的区别?

# 简要回答

浅拷贝(Shallow Copy)仅复制对象的成员变量值,包括指针变量的地址;

深拷贝(Deep Copy)会递归复制对象及其所有子对象,包括为指针成员分配新内存并复制内容,创建完全独立的新对象;

在C++中,当类包含指针成员时,浅拷贝会导致两个对象共享同一块内存,而深拷贝则让每个对象拥有自己独立的内存空间;

# 详细回答

拷贝操作主要通过拷贝构造函数和赋值运算符实现,深拷贝与浅拷贝的核心区别在于对指针或动态分配资源的管理方式

  • 浅拷贝:

仅复制对象的第一层成员变量

基本数据类型直接复制值

指针类型仅复制指针地址,新旧对象共享同一内存

由编译器生成的默认拷贝构造函数和赋值运算符实现

可能导致双重释放和悬垂指针问题

  • 深拷贝:

递归复制对象的所有层级

为指针成员分配新内存并复制内容

新旧对象完全独立,互不影响

需要手动实现拷贝构造函数和赋值运算符

避免内存问题但带来额外性能开销

在C++中,当类管理动态内存(如new分配的资源)时,必须使用深拷贝来避免内存管理问题。

  • 打个比方,便于理解:

想象你有一个带锁的箱子(对象),箱子里有贵重物品(指针指向的数据):

浅拷贝就像复制了一把钥匙(指针),新旧钥匙都能打开同一个箱子。

如果一个人用钥匙取走了物品,另一个人会发现箱子空了;

如果两个人都试图锁箱子(释放内存),会导致冲突。

深拷贝则是完全复制了整个箱子及其内容。

新旧箱子各有自己的钥匙和物品,互不干扰,可以安全地各自处理。

# 代码示例

#include <iostream>
using namespace std;

class Deep {
public:
    int* data;

    Deep(int value) {
        data = new int(value);
    }

    // 自定义拷贝构造函数实现深拷贝
    Deep(const Deep& other) {
        data = new int(*other.data);  // 分配新内存并复制值
    }

    // 赋值运算符重载实现深拷贝
    Deep& operator=(const Deep& other) {
        if (this != &other) {  // 防止自赋值
            delete data;       // 释放旧内存
            data = new int(*other.data);  // 分配新内存并复制值
        }
        return *this;
    }

    ~Deep() {
        delete data;  // 安全释放
    }
};

int main() {
    Deep obj1(10);
    Deep obj2 = obj1;  // 深拷贝

    *obj2.data = 20;

    cout << *obj1.data << endl;  // 10 (不受影响)
    cout << *obj2.data << endl;  // 20

    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

# 知识拓展

  • 知识图解

image

  • 使用场景

使用浅拷贝: 对象仅包含基本数据类型或POD(Plain Old Data)类型

明确需要共享资源时

性能敏感且确定不会导致问题的情况

使用深拷贝:

对象包含指针或动态分配的资源

需要完全独立的对象副本

多线程环境下避免共享状态

对象生命周期管理复杂的情况

  • 面试官可能追问

在STL容器中存储自定义对象时,拷贝语义如何影响容器行为?

STL容器采用值语义存储对象,任何插入操作都会触发拷贝构造(如push_back或insert)

若自定义类包含指针成员且未实现深拷贝,会导致多个对象共享同一内存,引发双重释放问题。

例如,vector存储含指针的Person对象时,默认浅拷贝会使容器内外指针指向同一地址,析构时重复释放内存而崩溃。

此外,继承场景下,向基类容器插入派生类对象会因拷贝丢失派生类特性("切片问题"),此时建议改用指针容器(如vector<Widget*>)或智能指针。

如何设计一个既能深拷贝又能共享资源的灵活类?

可通过引用计数+写时复制(COW)实现:默认共享资源(浅拷贝),仅在修改时触发深拷贝。

核心是维护共享指针(如shared_ptr)和引用计数,拷贝构造时递增计数,修改前检查计数,若>1则创建新副本并重置计数

Last Updated: 3/10/2026, 6:08:48 PM

← 如何禁止一个类被继承 this指针的原理 →

评论

验证登录状态...

侧边栏
夜间
卡码简历
代码随想录
卡码投递表🔥
2026群
添加客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记
鼓励/支持/赞赏Carl
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪