std::weak_ptr
定义于头文件 <memory>
。
template< class T > class weak_ptr;
std::weak_ptr 是一种智能指针,它持有一个对由 std::shared_ptr 管理的对象的非拥有(“弱”)引用。它必须转换为 std::shared_ptr 才能访问引用的对象。
std::weak_ptr 模拟临时所有权:当一个对象只需要在它存在时才被访问,并且它可能随时被其他人删除时,使用 std::weak_ptr 来跟踪该对象,并将其转换为 std::shared_ptr 以获取临时所有权。如果原始的 std::shared_ptr 在此时被销毁,则对象的生命周期会延长,直到临时的 std::shared_ptr 也被销毁。
std::weak_ptr 的另一个用途是打破由 std::shared_ptr 管理的对象形成的引用循环。如果这样的循环是孤立的(即,没有外部共享指针指向该循环),shared_ptr 引用计数将无法达到零,从而导致内存泄漏。为了防止这种情况,循环中的一个指针可以设置为弱指针。
成员类型
公共成员函数 | element_type | T (C++17 之前) std::remove_extent_t<T> (C++17 起) |
成员函数
公共成员函数 | (构造函数) | 创建一个新的 weak_ptr (公共成员函数) |
公共成员函数 | (析构函数) | 销毁一个 weak_ptr (公共成员函数) |
公共成员函数 | operator= | 赋值 weak_ptr (公共成员函数) |
修改器
公共成员函数 | reset | 释放对所管理对象的所有权 (公共成员函数) |
公共成员函数 | swap | 交换托管对象 (公共成员函数) |
观察者
公共成员函数 | use_count | 返回管理该对象的 shared_ptr 对象的数量 (公共成员函数) |
公共成员函数 | expired | 检查引用的对象是否已被删除 (公共成员函数) |
公共成员函数 | lock | 创建一个管理引用的对象的 shared_ptr (公共成员函数) |
公共成员函数 | owner_before | 提供基于所有者的弱指针排序 (公共成员函数) |
非成员函数
公共成员函数 | std::swap(std::weak_ptr) (C++11) | 特化 std::swap 算法 (函数模板) |
辅助类
公共成员函数 | std::atomic(std::weak_ptr) (C++20) | 原子弱指针 (类模板特化) |
推导指南 (C++17 起)
备注
与 std::shared_ptr 类似,weak_ptr 的典型实现存储两个指针:
- 指向控制块的指针;以及
- 从其构造的 std::shared_ptr 的存储指针。
一个单独的存储指针是必要的,以确保将 std::shared_ptr 转换为 weak_ptr 然后再转换回来能够正确工作,即使对于别名 std::shared_ptr 也是如此。在不将其锁定到 std::shared_ptr 中就无法访问 weak_ptr 中存储的指针。
示例
演示如何使用 lock 确保指针的有效性。
#include <iostream>
#include <memory>
std::weak_ptr<int> gw;
void observe()
{
std::cout << "gw.use_count() == " << gw.use_count() << "; ";
// we have to make a copy of shared pointer before usage:
if (std::shared_ptr<int> spt = gw.lock()) {
std::cout << "*spt == " << *spt << '\n';
}
else {
std::cout << "gw is expired\n";
}
}
int main()
{
{
auto sp = std::make_shared<int>(42);
gw = sp;
observe();
}
observe();
}
gw.use_count() == 1; *spt == 42
gw.use_count() == 0; gw is expired
缺陷报告
以下改变行为的缺陷报告已追溯应用于先前发布的 C++ 标准。
缺陷报告 | 应用于 | 发布时的行为 | 正确行为 |
---|---|---|---|
LWG 3001 | C++17 | element_type 没有更新以支持数组 | 已更新 |