跳到主要内容

std::weak_ptr

定义于头文件 <memory>

自 C++11 起
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_typeT (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 3001C++17element_type 没有更新以支持数组已更新

std::weak_ptr

定义于头文件 <memory>

自 C++11 起
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_typeT (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 3001C++17element_type 没有更新以支持数组已更新