导读:本期聚焦于小伙伴创作的《现代C++智能指针有哪些类型 shared_ptr和unique_ptr使用场景怎么对比》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《现代C++智能指针有哪些类型 shared_ptr和unique_ptr使用场景怎么对比》有用,将其分享出去将是对创作者最好的鼓励。

现代C++标准库提供了智能指针来管理动态分配的内存,核心目的是自动释放不再使用的内存,减少手动管理带来的错误。智能指针本质是一个模板类,行为类似指针,但会在合适的时机自动调用删除器释放所指向的对象。

现代C++智能指针有哪些类型 shared_ptr和unique_ptr使用场景怎么对比

现代C++智能指针的核心类型

标准库memory头文件中定义了三种主要的智能指针,各自有不同的设计目标和适用场景:

  • unique_ptr:独占所有权的智能指针,同一时间只能有一个unique_ptr指向某个对象,对象的所有权不可复制,只能转移。
  • shared_ptr:共享所有权的智能指针,多个shared_ptr可以指向同一个对象,内部通过引用计数记录指向该对象的指针数量,当计数归零时自动释放对象。
  • weak_ptr:弱引用智能指针,它指向shared_ptr管理的对象,但不会增加引用计数,主要用来解决shared_ptr的循环引用问题。

shared_ptr和unique_ptr的核心差异

两者的核心差异体现在所有权模型上,这直接决定了它们的使用限制和性能表现:

对比维度unique_ptrshared_ptr
所有权模式独占,不可复制共享,可复制
引用计数有,维护额外控制块
性能开销几乎和裸指针一致有控制块分配和计数更新的开销
线程安全本身不是线程安全,所有权转移需保证同步引用计数更新是线程安全的

shared_ptr和unique_ptr的使用场景对比

优先选择unique_ptr的场景

当明确某个动态对象只会被一个所有者持有,不需要共享所有权时,应该优先使用unique_ptr,它的开销最小,语义也最清晰。

比如函数内部动态创建临时对象,或者类的成员变量唯一持有某个资源的情况:

#include <memory>
#include <iostream>

// 定义一个简单的测试类
class TestObj {
public:
    TestObj() { std::cout << "TestObj构造" << std::endl; }
    ~TestObj() { std::cout << "TestObj析构" << std::endl; }
    void do_something() { std::cout << "执行操作" << std::endl; }
};

// 函数返回unique_ptr,转移所有权给调用方
std::unique_ptr<TestObj> create_obj() {
    // 创建unique_ptr管理动态对象
    return std::make_unique<TestObj>();
}

int main() {
    // 接收函数返回的unique_ptr,独占对象所有权
    std::unique_ptr<TestObj> obj = create_obj();
    obj->do_something();
    // 离开作用域时,unique_ptr自动释放对象,不需要手动delete
    return 0;
}

再比如工厂函数返回对象,明确返回的对象所有权交给调用方,不需要多个持有者的情况,也适合用unique_ptr。

优先选择shared_ptr的场景

当同一个动态对象需要被多个不同的所有者共享,且无法确定哪个所有者最后释放对象时,应该使用shared_ptr。

比如多个模块需要访问同一个配置对象,或者容器需要存储多个地方都会使用的动态对象:

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

class Config {
public:
    Config() { std::cout << "Config构造" << std::endl; }
    ~Config() { std::cout << "Config析构" << std::endl; }
    void print() { std::cout << "配置信息" << std::endl; }
};

int main() {
    // 创建共享的配置对象
    std::shared_ptr<Config> config = std::make_shared<Config>();
    // 多个shared_ptr共享同一个对象
    std::shared_ptr<Config> config2 = config;
    std::vector<std::shared_ptr<Config>> config_list;
    config_list.push_back(config);
    
    config->print();
    config2->print();
    // 此时引用计数为3,三个shared_ptr都指向同一个Config对象
    std::cout << "当前引用计数: " << config.use_count() << std::endl;
    // 逐个释放shared_ptr,最后引用计数归零时对象被析构
    return 0;
}

需要避免的使用误区

不要为了避免写unique_ptr的所有权转移代码,就无脑使用shared_ptr,shared_ptr的控制块分配和引用计数更新会带来额外的性能开销,在性能敏感的场景下影响比较明显。

另外不要用一个裸指针同时初始化多个shared_ptr,这会导致重复释放的问题:

#include <memory>

int main() {
    int* raw_ptr = new int(10);
    // 错误用法:两个shared_ptr独立管理同一个裸指针,会导致重复释放
    std::shared_ptr<int> sp1(raw_ptr);
    std::shared_ptr<int> sp2(raw_ptr); // 此处行为未定义,可能崩溃
    return 0;
}

如果确实需要共享裸指针管理的对象,应该先创建一个shared_ptr,再通过复制的方式得到其他shared_ptr。

总结

现代C++的智能指针体系中,unique_ptr是轻量且高效的独占所有权方案,适合大部分不需要共享的场景;shared_ptr是共享所有权的方案,适合多持有者的场景,但要承担额外的性能开销;weak_ptr则是shared_ptr的补充,用来解决循环引用问题。实际开发中应该根据所有权需求优先选择unique_ptr,只有在确实需要共享时才使用shared_ptr,这样能在保证内存安全的同时获得更好的性能。

shared_ptrunique_ptrweak_ptr智能指针修改时间:2026-06-21 01:09:34

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。