定义于头文件
template< class T > class weak_ptr; (C++11 起)
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
引用计数无法抵达零,而内存被泄露。能令环中的指针之一为弱指针以避免此情况。
std::weak_ptr<T>::weak_ptr
constexpr weak_ptr() noexcept; | (1) | (C++11 起) |
weak_ptr( const weak_ptr& r ) noexcept; | (2) | (C++11 起) |
template< class Y > | (2) | (C++11 起) |
template< class Y > | (2) | (C++11 起) |
weak_ptr( weak_ptr&& r ) noexcept; | (3) | (C++14 起) |
template< class Y > | (3) | (C++14 起) |
构造新的 weak_ptr
,潜在地与 r
共享对象的。
1) 默认构造函数。构造空 weak_ptr
。
2) 构造新的 weak_ptr
,它共享 r
所管理的对象。若 r
不管理对象,则 *this 亦不管理对象。模板重载不参与重载决议,除非 Y*
可隐式转换为 T*
,或 Y
是某类型 U
和某数 N
的“ N
个 U
的数组”类型,而 T
是“(可有 cv 限定的) U
的未知边界数组”类型 (C++17 起)。
3) 移动构造函数。从 r
移动 weak_ptr 实例到 *this
。之后, r
为空且 r.use_count()==0 。模板重载不参与重载决议,除非 Y*
可隐式转换为 T*
。
r | - | 将为此 std::weak_ptr 所查看的 std::shared_ptr 或 std::weak_ptr |
因为默认构造函数是 constexpr
,静态 weak_ptr
会在任何动态非局部初始化之前,作为静态非局部初始化的一部分初始化。这使得在任何静态对象的构造函数中使用 weak_ptr
是安全的。
- #include <memory>
- #include <iostream>
-
- struct Foo {};
-
- int main()
- {
- std::weak_ptr<Foo> w_ptr;
-
- {
- auto ptr = std::make_shared<Foo>();
- w_ptr = ptr;
- std::cout << "w_ptr.use_count() inside scope: " << w_ptr.use_count() << '\n';
- std::weak_ptr<Foo> w_ptr1(w_ptr);
- std::cout << "w_ptr1.use_count() inside scope: " << w_ptr.use_count() << '\n';
- }
-
- std::cout << "w_ptr.use_count() out of scope: " << w_ptr.use_count() << '\n';
- std::cout << "w_ptr.expired() out of scope: " << std::boolalpha << w_ptr.expired() << '\n';
- }
std::weak_ptr<T>::~weak_ptr
~weak_ptr(); (C++11 起)
销毁 weak_ptr
对象。对被管理对象不产生影响。
std::weak_ptr<T>::reset
void reset() noexcept; (C++11 起)
释放被管理对象的所有权。调用后 *this 不管理对象。
(无)
(无)
- #include <memory>
- #include <iostream>
-
- struct Foo {};
-
- int main()
- {
- std::shared_ptr<Foo> ptr = std::make_shared<Foo>();
- std::weak_ptr<Foo> w_ptr = ptr;
- std::weak_ptr<Foo> w_ptr1 = w_ptr;
- w_ptr.reset();
-
- std::cout << "ptr.use_count() out of scope: " << ptr.use_count() << '\n';
-
- std::cout << "w_ptr.use_count() out of scope: " << w_ptr.use_count() << '\n';
- std::cout << "w_ptr.expired() out of scope: " << std::boolalpha << w_ptr.expired() << '\n';
-
- std::cout << "w_ptr1.use_count() out of scope: " << w_ptr1.use_count() << '\n';
- std::cout << "w_ptr1.expired() out of scope: " << std::boolalpha << w_ptr1.expired() << '\n';
- }
std::weak_ptr<T>::swap
void swap( weak_ptr& r ) noexcept; (C++11 起)
交换 *this 与 r
的内容
r | - | 要与之交换内容的智能指针 |
(无)
- #include <memory>
- #include <iostream>
-
- struct Foo
- {
- int N;
- Foo(int n): N(n) {}
- };
-
- int main()
- {
- std::shared_ptr<Foo> ptr_1 = std::make_shared<Foo>(1);
- std::shared_ptr<Foo> ptr_2 = std::make_shared<Foo>(2);
-
- std::weak_ptr<Foo> w_ptr1 = ptr_1;
- std::weak_ptr<Foo> w_ptr2 = ptr_2;
-
- {
- std::shared_ptr<Foo> ptr1 = w_ptr1.lock() ;
- std::shared_ptr<Foo> ptr2 = w_ptr2.lock() ;
- std::cout << "ptr1 N: " << ptr1->N << '\n';
- std::cout << "ptr2 N: " << ptr2->N << '\n';
- }
-
- {
- w_ptr1.swap(w_ptr2);
- std::shared_ptr<Foo> ptr1 = w_ptr1.lock() ;
- std::shared_ptr<Foo> ptr2 = w_ptr2.lock() ;
- // 只交换std::weak_ptr
- std::cout << "ptr1 N: " << ptr1->N << '\n';
- std::cout << "ptr2 N: " << ptr2->N << '\n';
- // 不交换std::shared_ptr
- std::cout << "ptr_1 N: " << ptr_1->N << '\n';
- std::cout << "ptr_1 N: " << ptr_2->N << '\n';
- }
- }