C++ 标准库读书杂记7 Smart Pointer
发布日期:2021-05-10 05:00:41 浏览次数:26 分类:精选文章

本文共 2003 字,大约阅读时间需要 6 分钟。

C++没有内存回收机制,因此程序员在使用new创建对象时,必须手动使用delete释放内存。如果操作复杂,可能会遗漏delete,导致内存泄漏。为了简化内存管理,C++引入了智能指针(Smart Pointers),用于管理动态资源。

raw指针的局限性

使用raw pointer管理动态内存时,常见问题包括:

  • 丢忘释放内存,导致内存泄漏。
  • 在异常发生时,delete操作无法执行,同样引发内存泄漏。
  • 智能指针类型

    智能指针主要有三种:shared_ptrunique_ptrweak_ptrshared_ptr是最常用的,且其他人版本(如unique_ptrweak_ptr)可以协同工作。

    shared_ptr

    shared_ptr采用引用计数机制。多个shared_ptr指向同一内存区域,它们共同维护一个引用计数器。当引用次数为0时,才释放内存。

    注意事项

    • 循环引用:如果一个shared_ptr指向另一个shared_ptr,而被引用的对象没有shared_ptr释放该指针的话,就可能导致内存泄漏。weak_ptr适用于这种情况。
    • 构造与析构函数
      • 默认构造函数:shared_ptr(),无引用计数。
      • 初始化构造函数:接受一个T*指针或另一个shared_ptr
      • 析构函数会先检查引用计数器是否为0,若是则删除指针和引用计数器。

    赋值运算

    当将shared_ptr<T>对象赋值给另一个shared_ptr<T>对象时,会进行以下操作:

  • 原本的refCount自减。
  • 目标的refCount自加。
  • 目标的指针指向源的指针。
  • member functions

    shared_ptr提供丰富的功能:

    • construct:创建shared_ptr
    • destroy:释放内存。
    • operator=:赋值。
    • swap:交换两个shared_ptr
    • reset:重置指针。
    • get:获取指针。
    • operator*operator->:访问对象。
    • use_count:获取引用计数。
    • unique:检查是否为唯一拥有者。
    • operator bool:检查是否不为空。
    • owner_before:检查是否在资源恢复顺序中的位置。
    • lock:获取可移动的shared_ptr

    示例

    #include "shared_ptr.h"
    class Foo {
    public:
    Foo() { std::cout << "Foo...\n"; }
    ~Foo() { std::cout << "~Foo...\n"; }
    };
    // 接受foo_的函数
    void func_shared_ptr(const shared_ptr
    & foo_) {
    std::cout << "foo_.use_count = " << foo_.use_count() << '\n';
    }

    unique_ptr

    unique_ptr不共享指针,资源所有权只能通过移动转移。由于禁止复制,非常适合当内存资源由一个所有者管理时使用。移动操作提供了一种转移内存所有权的方式,可以避免复杂的资源管理。

    特点

    • 不能拷贝或赋值,除非使用std::move
    • 创建方式:传递new返回的指针给unique_ptr的构造函数。
    • 拷贝构造函数不存在,普通拷贝操作会报错。
    • 移动操作允许资源转移。

    示例

    // 创建unique_ptr
    unique_ptr
    pInt(new int(5));
    // 挾有资源的对象
    对象A pIntOwner(pInt);
    // 通过std::move转移资源所有权
    unique_ptr
    pIntMove(std::move(pInt));

    weak_ptr

    weak_ptrshared_ptr的弱引用,用于临时引用对象。当对象被释放时,weak_ptr也会失效。它特别适用于避免循环引用和临时引用对象。

    特点

    • weak_ptr不控制对象生命周期。
    • 当对象被释放时,weak_ptr失效。
    • 必须通过lock()获取可无效的shared_ptr才能使用。

    示例

    // 创建weak_ptr
    weak_ptr
    gw;
    void f() {
    auto spt = gw.lock();
    if (spt) {
    // 通过spt访问对象
    } else {
    // gw已经失效
    }
    }

    总结

    智能指针通过引用计数和移动机制,简化了动态内存管理。shared_ptr适合一般场景,unique_ptr适用于单所有者资源管理,weak_ptr用于临时引用或循环引用场景。选择合适的智能指针类型,可以提高代码的安全性和可维护性。

    上一篇:shell总结
    下一篇:C++ 标准库读书杂记6 Tuple

    发表评论

    最新留言

    很好
    [***.229.124.182]2025年04月28日 10时58分26秒