std::shared_ptr和std::unique_ptr有什么区别

std::shared_ptrstd::unique_ptr 都是 C++ 标准库中提供的智能指针,用于管理动态分配的对象的生命周期,但它们之间有一些重要的区别。以下是两者的主要区别:

1. 所有权模型

  • std::unique_ptr:

    • 独占所有权std::unique_ptr 表示独占所有权,即一个对象只能由一个 std::unique_ptr 拥有。当 std::unique_ptr 被销毁时,它所拥有的对象也会被销毁。
    • 不可复制std::unique_ptr 不能被复制,只能被移动(move)。这意味着你不能有两个 std::unique_ptr 指向同一个对象。
    • 适用于单个所有者:当你确定一个对象只有一个所有者时,使用 std::unique_ptr 是最佳选择。
  • std::shared_ptr:

    • 共享所有权std::shared_ptr 表示共享所有权,允许多个 std::shared_ptr 实例共享同一个对象的所有权。当最后一个 std::shared_ptr 被销毁时,它所拥有的对象才会被销毁。
    • 引用计数std::shared_ptr 内部维护一个引用计数,跟踪有多少个 std::shared_ptr 指向同一个对象。
    • 可复制std::shared_ptr 可以被复制。复制 std::shared_ptr 会增加引用计数,销毁 std::shared_ptr 会减少引用计数。
    • 适用于多个所有者:当你需要多个所有者共享同一个对象时,使用 std::shared_ptr 是合适的。

2. 性能

  • std::unique_ptr:

    • 轻量级std::unique_ptr 没有引用计数,因此它的开销比 std::shared_ptr 更小。
    • 更快:由于没有引用计数,std::unique_ptr 的性能通常更好。
  • std::shared_ptr:

    • 额外开销std::shared_ptr 需要维护引用计数,这会带来一定的性能开销。
    • 内存占用std::shared_ptr 需要额外的空间来存储引用计数,这可能会增加内存占用。

3. 用法

  • std::unique_ptr:

    • 适用于资源独占的情况,例如文件句柄、网络连接等。
    • 适用于单线程或多线程环境中的局部资源管理。
  • std::shared_ptr:

    • 适用于需要多个所有者的场景,例如在多线程环境中共享资源。
    • 适用于复杂的对象图,其中对象之间有相互引用的情况。

4. 自定义删除器

  • std::unique_ptr 和 std::shared_ptr 都支持自定义删除器(deleter),允许你指定如何释放资源。这对于管理自定义分配器或需要特殊清理逻辑的资源非常有用。

5. 原子性

  • std::shared_ptr:

    • 由于 std::shared_ptr 使用引用计数,它是线程安全的。引用计数的操作(如增加和减少)是原子的。
    • 但是,多个 std::shared_ptr 之间的赋值和比较操作仍然是非原子的,需要适当的同步机制。
  • std::unique_ptr:

    • std::unique_ptr 本身不是线程安全的,因为它不涉及引用计数。如果你需要在线程间传递 std::unique_ptr,需要使用适当的同步机制。

示例代码

 

cpp

深色版本

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "MyClass constructed\n"; }
    ~MyClass() { std::cout << "MyClass destructed\n"; }
};

void uniquePtrExample() {
    std::unique_ptr<MyClass> ptr(new MyClass());
    // ptr 不能被复制,只能被移动
    // std::unique_ptr<MyClass> ptr2 = ptr;  // 错误
    std::unique_ptr<MyClass> ptr2 = std::move(ptr);  // 正确
}

void sharedPtrExample() {
    std::shared_ptr<MyClass> ptr(new MyClass());
    // ptr 可以被复制
    std::shared_ptr<MyClass> ptr2 = ptr;  // 正确
    std::cout << "Reference count: " << ptr.use_count() << std::endl;  // 输出 2
}

int main() {
    uniquePtrExample();
    sharedPtrExample();
    return 0;
}

总结

  • std::unique_ptr 适用于独占所有权的场景,性能更好,开销更小。
  • std::shared_ptr 适用于共享所有权的场景,提供了引用计数和线程安全的引用计数操作,但会有额外的性能开销。

选择哪种智能指针取决于你的具体需求和设计。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值