You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

shared_ptr实际场景咨询:为何需多所有权而非用unique_ptr

一个务实的shared_ptr最佳实践场景:多视图共享文档对象

嘿,我完全懂你这种感觉——刚接触智能指针的时候,总觉得unique_ptr好像能包打天下,直到遇到那种**多个地方都需要访问同一个对象,而且谁都不是唯一的‘主人’**的场景。我给你举个非常真实的例子:支持多窗口/多标签页的文本编辑器,这绝对是shared_ptr的主场,用unique_ptr根本搞不定。

场景说明

假设你正在开发一个轻量文本编辑器,用户可以打开同一个文档的多个窗口(比如分屏对比内容,或者在不同标签页编辑同一文档)。每个窗口(我们叫它DocumentView)都需要读取和修改文档内容,而且文档的生命周期应该是:只要还有一个窗口在显示它,文档就不能被销毁;当所有窗口都关闭后,文档才自动释放内存。

这时候unique_ptr就歇菜了——因为unique_ptr强调“唯一所有权”,你没法把同一个unique_ptr交给多个DocumentView,赋值或者传递都会转移所有权,导致其他视图拿到的是悬空指针。而shared_ptr的引用计数机制正好完美匹配这个需求:每个视图持有一个shared_ptr<Document>,每次创建新视图计数+1,销毁视图计数-1,当计数降到0时,Document自动被销毁。

实用代码示例

#include <iostream>
#include <memory>
#include <vector>
#include <string>

// 文档类:存储文本内容的核心业务对象
class Document {
private:
    std::string content;
public:
    Document(const std::string& initial_content) : content(initial_content) {
        std::cout << "Document 被创建了!" << std::endl;
    }

    ~Document() {
        std::cout << "Document 被销毁了!" << std::endl;
    }

    // 修改文档内容
    void append_content(const std::string& text) {
        content += text;
    }

    // 获取文档内容
    const std::string& get_content() const {
        return content;
    }
};

// 文档视图类:代表一个显示/编辑文档的窗口
class DocumentView {
private:
    std::shared_ptr<Document> doc; // 持有文档的共享所有权
    std::string view_name;
public:
    DocumentView(std::shared_ptr<Document> document, const std::string& name) 
        : doc(std::move(document)), view_name(name) {
        std::cout << "视图 [" << view_name << "] 已创建,当前文档引用计数:" << doc.use_count() << std::endl;
    }

    ~DocumentView() {
        std::cout << "视图 [" << view_name << "] 被销毁,当前文档引用计数:" << doc.use_count() - 1 << std::endl;
    }

    // 在当前视图中编辑文档
    void edit_document(const std::string& text) {
        doc->append_content(text);
        std::cout << "视图 [" << view_name << "] 编辑后文档内容:\n" << doc->get_content() << std::endl;
    }
};

int main() {
    // 创建一个文档,用shared_ptr管理其生命周期
    auto doc = std::make_shared<Document>("初始文档内容\n");

    // 创建多个视图,共享同一个文档
    std::vector<std::unique_ptr<DocumentView>> views;
    views.emplace_back(std::make_unique<DocumentView>(doc, "主窗口"));
    views.emplace_back(std::make_unique<DocumentView>(doc, "分屏窗口1"));
    views.emplace_back(std::make_unique<DocumentView>(doc, "分屏窗口2"));

    // 用任意一个视图编辑文档,所有视图都会看到更新
    views[1]->edit_document("分屏窗口1添加的内容\n");

    // 关闭第一个视图(销毁对应的DocumentView对象)
    views.erase(views.begin());

    // 用剩下的第三个视图继续编辑
    views[1]->edit_document("分屏窗口2添加的内容\n");

    // 程序结束时,所有视图被销毁,文档最后自动销毁
    return 0;
}

为什么这是最优选择

这个场景里,shared_ptr是唯一合适的智能指针:

  • 用unique_ptr的话,你只能让一个视图拥有文档所有权,其他视图只能用裸指针,这会导致悬空指针的风险(比如拥有所有权的视图被销毁了,其他视图还在访问文档)。
  • 用裸指针的话,你需要手动跟踪所有引用文档的视图,在最后一个视图关闭时手动delete文档,这很容易出错(比如漏跟踪导致内存泄漏,或者重复释放)。
  • shared_ptr的引用计数机制自动帮我们处理了这些问题,代码简洁且安全,完全贴合“多个所有者共享对象”的真实业务需求。

内容的提问来源于stack exchange,提问作者code

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:37:22