
std::shared_ptr 和 std::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_ptrMyClass ptr(new MyClass()); // ptr 不能被复制只能被移动 // std::unique_ptrMyClass ptr2 ptr; // 错误 std::unique_ptrMyClass ptr2 std::move(ptr); // 正确 } void sharedPtrExample() { std::shared_ptrMyClass ptr(new MyClass()); // ptr 可以被复制 std::shared_ptrMyClass ptr2 ptr; // 正确 std::cout Reference count: ptr.use_count() std::endl; // 输出 2 } int main() { uniquePtrExample(); sharedPtrExample(); return 0; }总结std::unique_ptr 适用于独占所有权的场景性能更好开销更小。std::shared_ptr 适用于共享所有权的场景提供了引用计数和线程安全的引用计数操作但会有额外的性能开销。选择哪种智能指针取决于你的具体需求和设计。