C++中的深浅拷贝

1、浅拷贝

浅拷贝只复制对象的成员变量值,包括指针的值(地址),不复制指针指向的内容。

#include <iostream>

#include <cstring>

class ShallowString {

private:

char* data;

public:

// 构造函数

ShallowString(const char* str = "") {

data = new charstrlen(str) + 1;

strcpy(data, str);

std::cout << "Constructor called for: " << data << std::endl;

}

// 析构函数

~ShallowString() {

std::cout << "Destructor called for: " << data << std::endl;

delete\[\] data;

}

// 默认拷贝构造函数(浅拷贝)

// 编译器自动生成:ShallowString(const ShallowString& other) : data(other.data) {}

void print() const {

std::cout << "Data: " << data << " (" << (void*)data << ")" << std::endl;

}

void modify(const char* newStr) {

strcpy(data, newStr);

}

};

void demonstrateShallowCopyProblem() {

std::cout << "=== 浅拷贝问题演示 ===" << std::endl;

ShallowString str1("Hello");

ShallowString str2 = str1; // 浅拷贝!

std::cout << "\n原始状态:" << std::endl;

str1.print();

str2.print();

std::cout << "\n修改str2:" << std::endl;

str2.modify("World");

std::cout << "\n修改后:" << std::endl;

str1.print(); // 也被修改了!

str2.print();

std::cout << "\n问题:两个对象共享同一块内存!" << std::endl;

std::cout << "更严重的问题:双重释放!" << std::endl;

}

/*

输出示例:

=== 浅拷贝问题演示 ===

Constructor called for: Hello

原始状态:

Data: Hello (0x...)

Data: Hello (0x...) // 相同地址!

修改str2:

修改后:

Data: World (0x...) // 两个都变了!

Data: World (0x...)

问题:两个对象共享同一块内存!

更严重的问题:双重释放!

Destructor called for: World

Destructor called for: World // 第二次释放同一内存 -> 程序崩溃!

*/

2、深拷贝

深拷贝会复制指针指向的实际内容,创建一个全新的内存区域。

#include <iostream>

#include <cstring>

class DeepString {

private:

char* data;

public:

// 构造函数

DeepString(const char* str = "") {

data = new charstrlen(str) + 1;

strcpy(data, str);

std::cout << "Constructor called for: " << data << " at " << (void*)data << std::endl;

}

// 深拷贝构造函数

DeepString(const DeepString& other) {

data = new charstrlen(other.data) + 1;

strcpy(data, other.data);

std::cout << "Deep copy constructor called" << std::endl;

std::cout << " From: " << other.data << " at " << (void*)other.data << std::endl;

std::cout << " To: " << data << " at " << (void*)data << std::endl;

}

// 深拷贝赋值运算符

DeepString& operator=(const DeepString& other) {

if (this != &other) { // 自赋值检查

delete\[\] data; // 释放原有内存

data = new charstrlen(other.data) + 1;

strcpy(data, other.data);

std::cout << "Deep copy assignment called" << std::endl;

}

return *this;

}

// 析构函数

~DeepString() {

std::cout << "Destructor called for: " << data << " at " << (void*)data << std::endl;

delete\[\] data;

}

void print() const {

std::cout << "Data: " << data << " (" << (void*)data << ")" << std::endl;

}

void modify(const char* newStr) {

strcpy(data, newStr);

}

};

void demonstrateDeepCopy() {

std::cout << "=== 深拷贝演示 ===" << std::endl;

DeepString str1("Hello");

DeepString str2 = str1; // 深拷贝

std::cout << "\n原始状态:" << std::endl;

str1.print();

str2.print();

std::cout << "\n修改str2:" << std::endl;

str2.modify("World");

std::cout << "\n修改后:" << std::endl;

str1.print(); // 保持不变

str2.print(); // 已修改

std::cout << "\n赋值操作:" << std::endl;

DeepString str3("Test");

str3 = str1; // 深拷贝赋值

str3.print();

}

/*

输出示例:

=== 深拷贝演示 ===

Constructor called for: Hello at 0x...

Deep copy constructor called

From: Hello at 0x...

To: Hello at 0x... // 不同地址!

原始状态:

Data: Hello (0x...)

Data: Hello (0x...) // 不同地址

修改str2:

修改后:

Data: Hello (0x...) // 保持不变

Data: World (0x...) // 已修改

赋值操作:

Constructor called for: Test at 0x...

Deep copy assignment called

Data: Hello (0x...)

Destructor called for: Hello at 0x...

Destructor called for: World at 0x...

Destructor called for: Hello at 0x...

*/

3、用通俗易懂的语言来说

浅拷贝:共享账号

想象你有一个网易云音乐账号(里面有你的歌单、收藏):

// 这是你的原始账号

网易云账号 我的账号("小明", "密码123");

我的账号.添加歌单("我最爱的歌");

// 浅拷贝:把你的账号信息告诉朋友

网易云账号 朋友的账号 = 我的账号; // 浅拷贝

发生了什么?

  • 朋友没有自己的账号,只是知道了你的账号密码

  • 你们登录的是同一个账号

  • 如果朋友删除了一首歌 → 你的歌单也没了!

  • 如果朋友改了密码 → 你也登录不了了!

深拷贝:独立账户

// 深拷贝:给朋友创建全新账号

网易云账号 朋友的账号 = 我的账号.深拷贝();

发生了什么?

  • 网易云为朋友新建了一个完全独立的账号

  • 把你所有的歌单、收藏复制一份到新账号

  • 朋友删歌 → 你的歌单不受影响

  • 朋友改密码 → 你的密码不变

最简记忆法:

  • 浅 = 浅尝辄止,只复制表面(指针)

  • 深 = 深入到底,复制全部内容

相关推荐
Joy T5 小时前
Agent 确定性上下文设计:从 Prompt 参数注入到能力分层
java·开发语言·微服务·架构·prompt·agent context
专注仿真8 小时前
引擎扩展性与集成设计深度剖析:从 14 个扩展点到 DIS→HLA 演进之路
开发语言·算法·仿真引擎·推演引擎
Best-Wishes8 小时前
科来网络分析系统(技术交流版)使用说明书
开发语言·junit·php
代码不停9 小时前
自动化测试(java)
java·开发语言·selenium·自动化
别动我齐刘海10 小时前
Linux 系统调试学习1
linux·运维·服务器·c++·学习·机器学习·机器人
鬼手点金11 小时前
opencode-rules 插件
java·开发语言·前端·人工智能·chrome·git·github
爱上网的小舟11 小时前
星际战士2启动错误怎么办?5种游戏报错解决方法
开发语言·php
阿里嘎多学长12 小时前
2026-10-12 GitHub 热点项目精选
开发语言·程序员·github·代码托管
wangchunyu11413 小时前
Python 数据可视化实战入门教程
开发语言·python·信息可视化
学逆向的14 小时前
C 突破编译器限制
c语言·开发语言·网络安全