面试题:介绍 C++ 中三种智能指针的使用场景?

在 C++ 中,智能指针是用于自动管理动态内存的工具,可以避免内存泄漏和悬空指针等问题。

C++11 引入了三种主要的智能指针:std::unique_ptrstd::shared_ptr 和 std::weak_ptr

以下是它们的使用场景和特点:


1. std::unique_ptr

  • 特点
    • 独占所有权:同一时间只能有一个 unique_ptr 指向某个对象。
    • 不能复制,只能移动(通过 std::move)。
    • 轻量级,性能开销小。
  • 使用场景
    • 管理独占资源的生命周期(如动态数组、文件句柄等)。
    • 需要明确资源所有权的场景。
  • 示例
    #include <memory>
    #include <iostream>
    
    int main() {
        std::unique_ptr<int> ptr = std::make_unique<int>(10); // 创建 unique_ptr
        std::cout << *ptr << std::endl; // 输出 10
    
        // std::unique_ptr<int> ptr2 = ptr; // 错误:不能复制
        std::unique_ptr<int> ptr2 = std::move(ptr); // 正确:移动语义
        if (!ptr) {
            std::cout << "ptr is now null" << std::endl;
        }
        return 0;
    }

2. std::shared_ptr

  • 特点
    • 共享所有权:多个 shared_ptr 可以指向同一个对象。
    • 使用引用计数管理资源生命周期,当引用计数为 0 时自动释放资源。
    • 支持复制和移动。
    • 性能开销较大(需要维护引用计数)。
  • 使用场景
    • 多个对象共享同一资源的场景。
    • 需要共享所有权的复杂数据结构(如图、树等)。
  • 示例
    #include <memory>
    #include <iostream>
    
    int main() {
        std::shared_ptr<int> ptr1 = std::make_shared<int>(10); // 创建 shared_ptr
        std::shared_ptr<int> ptr2 = ptr1; // 复制 shared_ptr
    
        std::cout << *ptr1 << " " << *ptr2 << std::endl; // 输出 10 10
        std::cout << ptr1.use_count() << std::endl; // 输出 2(引用计数)
        return 0;
    }

3. std::weak_ptr

  • 特点
    • 弱引用:不增加引用计数,不影响资源的生命周期。
    • 需要与 shared_ptr 配合使用。
    • 用于解决 shared_ptr 的循环引用问题。
  • 使用场景
    • 解决 shared_ptr 的循环引用问题(如双向链表、观察者模式等)。
    • 需要观察资源但不影响其生命周期的场景。
  • 示例
    #include <memory>
    #include <iostream>
    
    int main() {
        std::shared_ptr<int> sharedPtr = std::make_shared<int>(10);
        std::weak_ptr<int> weakPtr = sharedPtr; // 创建 weak_ptr
    
        if (auto lockedPtr = weakPtr.lock()) { // 尝试提升为 shared_ptr
            std::cout << *lockedPtr << std::endl; // 输出 10
        } else {
            std::cout << "Resource is no longer available" << std::endl;
        }
    
        sharedPtr.reset(); // 释放资源
        if (weakPtr.expired()) { // 检查资源是否已释放
            std::cout << "Resource is expired" << std::endl;
        }
        return 0;
    }

4. 三种智能指针的对比

特性std::unique_ptrstd::shared_ptrstd::weak_ptr
所有权独占共享无所有权(弱引用)
复制不支持支持支持
移动支持支持支持
引用计数
性能开销
使用场景独占资源共享资源解决循环引用或观察资源

5. 总结

  • std::unique_ptr:适用于独占资源的场景,性能开销小。
  • std::shared_ptr:适用于共享资源的场景,支持引用计数。
  • std::weak_ptr:适用于解决循环引用或观察资源的场景,不增加引用计数。

合理选择智能指针可以显著提高代码的安全性和可维护性,避免内存泄漏和悬空指针等问题。

THE END
点赞13 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容