三分钟读懂C++深浅拷贝:避免常见陷阱!

开发
智能指针就像是魔法世界中的扫地机器人,自动帮你清理和管理资源,让你专注于创造更多的魔法奇迹!

嘿!想象一下你是个小魔法师,手里有一本超级无敌珍贵的魔法书,里面藏着各种神奇的咒语和配方。某天,你最好的魔法师朋友看到你念咒语变出了一只可爱的小兔子,兴奋地问你能不能也学习这些魔法...

浅拷贝:一本书的两个主人

想象一下,你有一本超级珍贵的魔法书,里面记载着各种神奇咒语 🪄。有一天,你的好朋友特别想要这本书,于是你用了个复制咒语(浅拷贝)。但是!这个咒语有点调皮,它并没有真的复制出一本新书,而是给了你朋友一个新书签,指向的还是你那本原始的魔法书!

class MagicBook {
    char* spells;  // 魔法咒语在这里 ✨
public:
    MagicBook(const char* text) {
        spells = new char[strlen(text) + 1];  // 为咒语腾出空间 📝
        strcpy(spells, text);  // 把咒语写进书里 ✍️
    }
};

// 哎呀!这样复制书是很危险的 ⚠️
MagicBook book2 = book1;  // 两个魔法师共享一本书,太冒险了!🙈

这下可有趣了!如果你的朋友不小心把书弄脏了或者弄丢了(对象被销毁),你的书也会跟着消失。因为实际上你们根本就是在共用同一本书嘛!就像两个人拿着同一本书的钥匙,一个人把书扔了,另一个人也找不到书了!这就是浅拷贝带来的"一损俱损"的尴尬情况啦!

什么时候需要深拷贝?让魔法告诉你!

想象一下,当你的魔法书里藏着一些特殊的宝物(指针成员)或者神奇的空间袋(动态分配的资源)时,简单的复制咒语可不够用啦!这时候就需要一个更强大的深拷贝魔法,它能完完整整地复制出一本全新的魔法书,让每位魔法师都拥有属于自己的独立宝藏!

来看看这本超级魔法书是怎么施展深拷贝魔法的吧:

class AdvancedMagicBook {
    char* title;         // 魔法书的真名 📚
    int* pageNumbers;    // 神秘页码 🔢
    size_t pageCount;    // 书的厚度 📏
    
public:
    // 创造一本全新的魔法书 🎨
    AdvancedMagicBook(const char* bookTitle, size_t pages) {
        pageCount = pages;
        title = new char[strlen(bookTitle) + 1];      // 为书名开辟魔法空间 ✨
        strcpy(title, bookTitle);                     // 写下神秘的书名 ✍️
        pageNumbers = new int[pages];                 // 为每页施加编号魔法 🎯
        for(size_t i = 0; i < pages; i++) {
            pageNumbers[i] = i + 1;
        }
    }
    
    // 完美复制魔法书的咒语 🌟
    AdvancedMagicBook(const AdvancedMagicBook& other) {
        pageCount = other.pageCount;
        
        title = new char[strlen(other.title) + 1];    // 复制书名魔法 📝
        strcpy(title, other.title);
        
        pageNumbers = new int[pageCount];             // 复制页码魔法 🎨
        memcpy(pageNumbers, other.pageNumbers, pageCount * sizeof(int));
    }
    
    // 魔法书使用完毕,清理咒语 🧹
    ~AdvancedMagicBook() {
        delete[] title;         // 消除书名魔法 ✨
        delete[] pageNumbers;   // 清除页码魔法 🌟
    }
};

这样,每位魔法师都能拥有自己独一无二的魔法书啦!再也不用担心和其他魔法师共用一本书带来的各种麻烦了!

深拷贝小贴士:魔法师必读

亲爱的魔法师朋友们,在使用深拷贝魔法时要特别小心哦!想象一下,当你复制一本超大的魔法书时,需要消耗不少魔法能量呢(占用更多内存)!就像搬家一样,把所有东西都复制一遍确实很累人。

有时候施展深拷贝魔法可能会遇到一些小意外,比如魔法能量不够用了(内存分配失败)。别担心,我们有一个超级安全的魔法配方 🪄,它能确保即使魔法失败了,你的宝贵魔法书也不会受到任何损害!

// 看看这个超级安全的魔法配方 ✨
AdvancedMagicBook& operator=(const AdvancedMagicBook& other) {
    if (this != &other) {  // 先确认不是自己给自己施法 🤔
        // 准备新的魔法材料 🎨
        char* newTitle = new char[strlen(other.title) + 1];
        int* newPages = new int[other.pageCount];
        
        // 小心翼翼地复制魔法内容 ✍️
        strcpy(newTitle, other.title);
        memcpy(newPages, other.pageNumbers, other.pageCount * sizeof(int));
        
        // 清理旧的魔法痕迹 🧹
        delete[] title;
        delete[] pageNumbers;
        
        // 注入新的魔法能量 ⚡
        title = newTitle;
        pageNumbers = newPages;
        pageCount = other.pageCount;
    }
    return *this;
}

不过等等!现代魔法世界已经发展出了更智能的法术啦!它们就像会自动打扫的扫帚一样,帮我们处理各种复杂的资源管理问题。快来看看这个超酷的智能魔法吧!

智能魔法:使用智能指针

嘿,亲爱的魔法师朋友们!现代 C++ 就像是魔法世界中的一场革命,为我们带来了更智能的资源管理方式!想象一下,智能指针就像是你的小助手,帮你打理一切复杂的资源问题,让你轻松无忧地施展魔法!

#include <memory>

class ModernMagicBook {
    std::unique_ptr<char[]> spells;  // 独一无二的魔法咒语 📜
    std::shared_ptr<int> usageCount; // 共享的魔法能量计数器 🔋
    
public:
    ModernMagicBook(const char* text) {
        spells = std::make_unique<char[]>(strlen(text) + 1); // 为咒语开辟独特空间 ✨
        strcpy(spells.get(), text); // 将咒语铭刻在书中 🖋️
        usageCount = std::make_shared<int>(0); // 初始化魔法能量计数器 🔢
    }
    
    // 使用智能指针,编译器生成的拷贝构造函数就能正确处理资源了!✨
};

智能指针就像是魔法世界中的扫地机器人,自动帮你清理和管理资源,让你专注于创造更多的魔法奇迹!

总结

  • 浅拷贝适用于简单的值类型对象
  • 当类包含指针或动态资源时,必须实现深拷贝
  • 考虑使用智能指针来自动管理资源
  • 记住编写析构函数、拷贝构造函数和赋值运算符的规则

现在你已经掌握了深浅拷贝的魔法精髓,去创造你自己的魔法世界吧!

责任编辑:赵宁宁 来源: everystep
相关推荐

2021-10-27 05:47:53

通信协议协议网络技术

2024-05-16 11:13:16

Helm工具release

2009-11-09 12:55:43

WCF事务

2024-12-18 10:24:59

代理技术JDK动态代理

2023-12-27 08:15:47

Java虚拟线程

2024-01-16 07:46:14

FutureTask接口用法

2022-02-17 09:24:11

TypeScript编程语言javaScrip

2021-04-20 13:59:37

云计算

2024-08-30 08:50:00

2020-06-30 10:45:28

Web开发工具

2013-06-28 14:30:26

棱镜计划棱镜棱镜监控项目

2024-12-17 08:10:00

C++20LambdaC++

2021-12-17 07:47:37

IT风险框架

2020-06-29 07:42:20

边缘计算云计算技术

2024-07-05 09:31:37

2009-11-05 16:04:19

Oracle用户表

2021-02-03 14:31:53

人工智能人脸识别

2023-12-04 18:13:03

GPU编程

2024-10-15 09:18:30

2024-01-12 07:38:38

AQS原理JUC
点赞
收藏

51CTO技术栈公众号