weak_ptr

回绕弱链接指针。

语法

template<class T> class weak_ptr;

参数

T
由弱指针控制的类型。

注解

这个类模板描述了一个指向由一个或多个 shared_ptr 对象管理的资源的对象。 指向某个资源的 weak_ptr 对象不会影响该资源的引用计数。 当最后一个管理该资源 shared_ptr 的对象被销毁时,则即使存在指向该资源的 weak_ptr 对象,该资源也将被释放。 此行为对于避免数据结构中的循环至关重要。

在以下情况下 weak_ptr 对象将指向某个资源:如果该对象是从拥有该资源的 shared_ptr 对象构造而成;如果是从指向该资源的 weak_ptr 对象构造而成;或者使用 operator= 将该资源分配到了该对象。 weak_ptr 对象不提供直接访问其所指向的资源的权限。 需要使用该资源的代码可通过一个 shared_ptr 对象来执行该操作,该对象通过调用成员函数 lock 创建并拥有该资源。 weak_ptr 对象在其所指向的资源被释放时已过期,因为所有拥有该资源的 shared_ptr 对象已被销毁。 调用已过期的 weak_ptr 对象上的 lock 将创建一个空 shared_ptr 对象。

weak_ptr 对象不指向任何资源并且没有控制块。 其成员函数 lock 将返回一个空 shared_ptr 对象。

当两个或多个由 shared_ptr 对象控制的资源保留有相互引用的 shared_ptr 对象时,会发生循环。 例如,具有三个元素的循环的链接列表有一个头节点 N0;该节点保留有一个拥有下一个节点 N1shared_ptr 对象;该节点保留有一个拥有下一个节点 N2shared_ptr 对象;反过来,该节点保留有一个拥有头节点 N0shared_ptr 对象,由此形成闭合循环。 在这种情况下,引用计数从不变为零,并且从不释放循环中的节点。 若要消除循环,最后一个节点 N2 应保留指向 N0weak_ptr 对象,而不是 shared_ptr 对象。 由于 weak_ptr 对象不拥有 N0,因此不会影响 N0 的引用计数,并且销毁该程序对头节点的最后一个引用时,也将销毁列表中的节点。

成员

名称 说明
构造函数
weak_ptr 构造一个 weak_ptr
析构函数
~weak_ptr 销毁 weak_ptr
Typedef
element_type 元素的类型。
成员函数
expired 测试所属权是否已过期。
lock 获取资源的独占所属权。
owner_before 如果此 weak_ptr 排在提供的指针之前(或小于该指针),则返回 true
reset 释放所拥有的资源。
swap 交换两个 weak_ptr 对象。
use_count 计算 shared_ptr 对象的数目。
运算符
operator= 替换所拥有的资源。

element_type

元素的类型。

typedef T element_type; // through C++17
using element_type = remove_extent_t<T>; // C++20

备注

该类型是模板参数 T 的同义词。

示例

// std__memory__weak_ptr_element_type.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::shared_ptr<int> sp0(new int(5));
    std::weak_ptr<int> wp0(sp0);
    std::weak_ptr<int>::element_type val = *wp0.lock();

    std::cout << "*wp0.lock() == " << val << std::endl;

    return (0);
}
*wp0.lock() == 5

expired

测试所有权是否已过期,即已删除引用的对象。

bool expired() const noexcept;

备注

如果 *this 已过期,则成员函数返回 true;否则将返回 false

示例

// std__memory__weak_ptr_expired.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::weak_ptr<int> wp;

    {
        std::shared_ptr<int> sp(new int(10));
        wp = sp;
        std::cout << "wp.expired() == " << std::boolalpha
            << wp.expired() << std::endl;
        std::cout << "*wp.lock() == " << *wp.lock() << std::endl;
    }

    // check expired after sp is destroyed
    std::cout << "wp.expired() == " << std::boolalpha
        << wp.expired() << std::endl;
    std::cout << "(bool)wp.lock() == " << std::boolalpha
        << (bool)wp.lock() << std::endl;

    return (0);
}
wp.expired() == false
*wp.lock() == 10
wp.expired() == true
(bool)wp.lock() == false

lock

获取共享资源的所有权的 shared_ptr

shared_ptr<T> lock() const noexcept;

备注

如果 *this 已过期,则成员函数返回一个空 shared_ptr 对象;否则它将返回拥有 *this 指向的资源的shared_ptr<T> 对象。 返回等效于原子执行 expired() ? shared_ptr<T>() : shared_ptr<T>(*this) 的值。

示例

// std__memory__weak_ptr_lock.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::weak_ptr<int> wp;

    {
        std::shared_ptr<int> sp(new int(10));
        wp = sp;
        std::cout << "wp.expired() == " << std::boolalpha
            << wp.expired() << std::endl;
        std::cout << "*wp.lock() == " << *wp.lock() << std::endl;
    }

    // check expired after sp is destroyed
    std::cout << "wp.expired() == " << std::boolalpha
        << wp.expired() << std::endl;
    std::cout << "(bool)wp.lock() == " << std::boolalpha
        << (bool)wp.lock() << std::endl;

    return (0);
}
wp.expired() == false
*wp.lock() == 10
wp.expired() == true
(bool)wp.lock() == false

operator=

替换所拥有的资源。

weak_ptr& operator=(const weak_ptr& ptr) noexcept;

template <class Other>
weak_ptr& operator=(const weak_ptr<Other>& ptr) noexcept;

template <class Other>
weak_ptr& operator=(const shared_ptr<Other>& ptr) noexcept;

参数

Other
由参数共享指针或弱指针控制的类型。

ptr
要复制的弱指针或共享指针。

备注

这些运算符均会释放 *this 当前指向的资源,并将 ptr 命名的资源所有权分配给 *this。 如果运算符操作失败,则保持 *this 不变。 每个运算符的效果等效于 weak_ptr(ptr).swap(*this)

示例

// std__memory__weak_ptr_operator_as.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::shared_ptr<int> sp0(new int(5));
    std::weak_ptr<int> wp0(sp0);
    std::cout << "*wp0.lock() == " << *wp0.lock() << std::endl;

    std::shared_ptr<int> sp1(new int(10));
    wp0 = sp1;
    std::cout << "*wp0.lock() == " << *wp0.lock() << std::endl;

    std::weak_ptr<int> wp1;
    wp1 = wp0;
    std::cout << "*wp1.lock() == " << *wp1.lock() << std::endl;

    return (0);
}
*wp0.lock() == 5
*wp0.lock() == 10
*wp1.lock() == 10

owner_before

如果此 weak_ptr 排在提供的指针之前(或小于该指针),则返回 true

template <class Other>
bool owner_before(const shared_ptr<Other>& ptr) const noexcept;

template <class Other>
bool owner_before(const weak_ptr<Other>& ptr) const noexcept;

参数

ptr
shared_ptrweak_ptrlvalue 引用。

备注

如果 *thisptr 之前已排序,则模板成员函数返回 true

reset

释放拥有的资源。

void reset() noexcept;

注解

该成员函数将释放 *this 指向的资源,并将 *this 转换为空 weak_ptr 对象。

示例

// std__memory__weak_ptr_reset.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::shared_ptr<int> sp(new int(5));
    std::weak_ptr<int> wp(sp);
    std::cout << "*wp.lock() == " << *wp.lock() << std::endl;
    std::cout << "wp.expired() == " << std::boolalpha
        << wp.expired() << std::endl;

    wp.reset();
    std::cout << "wp.expired() == " << std::boolalpha
        << wp.expired() << std::endl;

    return (0);
}
*wp.lock() == 5
wp.expired() == false
wp.expired() == true

swap

交换两个 weak_ptr 对象。

void swap(weak_ptr& wp) noexcept;

还包括专用化:

template<class T>
void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;

参数

wp
要交换的弱指针。

注解

swap 之后,最初由 *this 指向的资源随后由 wp 指向,以及最初由 wp 指向的资源随后由 *this 指向。 此函数不会更改这两个资源的引用计数,也不会引发任何异常。 模板专用化的效果等效于 a.swap(b)

示例

// std__memory__weak_ptr_swap.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::shared_ptr<int> sp1(new int(5));
    std::shared_ptr<int> sp2(new int(10));
    std::cout << "*sp1 == " << *sp1 << std::endl;

    sp1.swap(sp2);
    std::cout << "*sp1 == " << *sp1 << std::endl;

    swap(sp1, sp2);
    std::cout << "*sp1 == " << *sp1 << std::endl;
    std::cout << std::endl;

    std::weak_ptr<int> wp1(sp1);
    std::weak_ptr<int> wp2(sp2);
    std::cout << "*wp1 == " << *wp1.lock() << std::endl;

    wp1.swap(wp2);
    std::cout << "*wp1 == " << *wp1.lock() << std::endl;

    swap(wp1, wp2);
    std::cout << "*wp1 == " << *wp1.lock() << std::endl;

    return (0);
}
*sp1 == 5
*sp1 == 10
*sp1 == 5

*wp1 == 5
*wp1 == 10
*wp1 == 5

use_count

计算拥有共享资源的 shared_ptr 对象的数目。

long use_count() const noexcept;

备注

成员函数将返回拥有 *this 指向的资源的 shared_ptr 对象数量。

示例

// std__memory__weak_ptr_use_count.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::shared_ptr<int> sp1(new int(5));
    std::weak_ptr<int> wp(sp1);
    std::cout << "wp.use_count() == "
        << wp.use_count() << std::endl;

    std::shared_ptr<int> sp2(sp1);
    std::cout << "wp.use_count() == "
        << wp.use_count() << std::endl;

    return (0);
}
wp.use_count() == 1
wp.use_count() == 2

weak_ptr

构造一个 weak_ptr

constexpr weak_ptr() noexcept;

weak_ptr(const weak_ptr& wp) noexcept;

weak_ptr(weak_ptr&& wp) noexcept;

template <class Other>
weak_ptr(const weak_ptr<Other>& wp) noexcept;

template <class Other>
weak_ptr(weak_ptr<Other>&& sp) noexcept;

template <class Other>
weak_ptr(const shared_ptr<Other>& sp) noexcept;

参数

Other
由参数共享/弱指针控制的类型。 除非 Other*element_type* 兼容,否则这些构造函数不参与重载决策。

wp
要复制的弱指针。

sp
要复制的共享指针。

备注

默认构造函数构造一个空 weak_ptr 对象。 如果参数指针为空,则采用参数的每个构造函数将构造一个空 weak_ptr 对象。 否则,它们会构造一个指向由参数命名的资源的 weak_ptr 对象。 共享对象的引用计数不会更改。

示例

// std__memory__weak_ptr_construct.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::weak_ptr<int> wp0;
    std::cout << "wp0.expired() == " << std::boolalpha
        << wp0.expired() << std::endl;

    std::shared_ptr<int> sp1(new int(5));
    std::weak_ptr<int> wp1(sp1);
    std::cout << "*wp1.lock() == "
        << *wp1.lock() << std::endl;

    std::weak_ptr<int> wp2(wp1);
    std::cout << "*wp2.lock() == "
        << *wp2.lock() << std::endl;

    return (0);
}
wp0.expired() == true
*wp1.lock() == 5
*wp2.lock() == 5

~weak_ptr

销毁 weak_ptr

~weak_ptr();

备注

析构函数会销毁此 weak_ptr,但不会影响其存储指针指向的对象的引用计数。

另请参阅

头文件引用
<memory>
shared_ptr