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
;该节点保留有一个拥有下一个节点 N1
的 shared_ptr
对象;该节点保留有一个拥有下一个节点 N2
的 shared_ptr
对象;反过来,该节点保留有一个拥有头节点 N0
的 shared_ptr
对象,由此形成闭合循环。 在这种情况下,引用计数从不变为零,并且从不释放循环中的节点。 若要消除循环,最后一个节点 N2
应保留指向 N0
的 weak_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= |
替换所拥有的资源。 |
元素的类型。
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
测试所有权是否已过期,即已删除引用的对象。
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
获取共享资源的所有权的 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
替换所拥有的资源。
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
如果此 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_ptr
或 weak_ptr
的 lvalue
引用。
如果 *this
在 ptr
之前已排序,则模板成员函数返回 true
。
释放拥有的资源。
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
交换两个 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
计算拥有共享资源的 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
。
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
,但不会影响其存储指针指向的对象的引用计数。