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");

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

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

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

发生了什么?

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

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

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

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

深拷贝:独立账户

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

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

发生了什么?

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

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

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

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

最简记忆法:

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

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

相关推荐
xiaoye-duck2 小时前
《C++ 项目:手写大模型接入 SDK》ChatGPT接口设计(中):全量响应实现和测试
网络·c++·语言模型·chatgpt
揽星河..2 小时前
【C语言】指针
c语言·开发语言
小小数媒成员2 小时前
UGUI原理(一)
开发语言·游戏·unity·游戏引擎
速易达网络2 小时前
Three.js 动画入门教学:从场景搭建到流畅动效
开发语言·javascript·ecmascript
東隅已逝,桑榆非晚2 小时前
算法3.双指针法-快乐数
c++·笔记·学习·算法
福大大架构师每日一题2 小时前
excelize v2.11.1发布:Go 1.26.0起步,16项安全修复与嵌入对象能力全面升级
开发语言·安全·golang
Sarvartha2 小时前
集合概述 & Collection 接口
开发语言
lhbweilai3 小时前
QT项目(串口助手)
开发语言·qt
eggwyw3 小时前
C++相交链表和反转链表详解
开发语言·c++
杜 硕3 小时前
从零开始的C++生活——第六讲——02
c++·算法·生活