C++ weak_ptr简介及实例

202 阅读4分钟

C++ weak_ptr

C++ weak_ptr简介

C++ weak_ptr 是标准库的一部分,它被用来保存任何由另一个标准库指针(称为 shared_ptr )管理的对象的弱引用,这意味着 weak_ptr 被用来将它最终转换为 shared_ptr。从 weak_ptr 最后转换的 shared_ptr 被用来访问被引用的对象。一旦一个 weak_ptr 被转换为 shared_ptr,它就失去了永久停留的能力,这标志着它的存在是暂时的。访问 weak_ptr 然后提供访问引用对象的能力并不是一种推荐的方式。

语法

template< class T > class weak_ptr;

C++ weak_ptr 的语法流程是这样的:作为 T 类传递的参数被用于弱指针控制的类型。

weak_ptr 在 C++ 中如何工作?

在任何高级语言中,每个指针都主要用于对象的引用,然后访问数组中以某种组织形式存在的元素。C++中的弱指针也是如此。整个类模板描述了 weak_ptr 的工作流程。

  • 最初用于引用对象的 weak_ptr 不是实际的指针,因为在对象引用和赋值方面,它被认为是一个临时指针。
  • 但是一旦 weak_ptr 获得了对 share_ptr 的最终控制或授权,那么在对象访问和引用方面就会变得简单和精简。
  • 这种共享和协调,或者说,在 weak_ptr 和 share_ptr 之间切换访问和引用,主要用于避免数据结构中的长周期。
  • 当 share_ptr 在分配和分析管理资源时承担全部责任时,weak_ptr 失去了所有的控制权并被删除。
  • 一个 weak_ptr 从来没有给予直接访问元素的能力;相反,它通过 shared_ptr 对象利用需要使用资源的代码,该对象通过调用称为 lock 的成员函数拥有整个代码。
  • 一旦为资源分配和控制任何块而调用lock或weak_ptr,一个空的weak_ptr对象就被创建。
  • 一旦锁或 weak_ptr 被大多数 shared_ptr 对象相互引用或持有,整个周期就完成了。
  • 它在share_ptr的帮助下突出地使用了所有的资源,而不是只使用weak_ptr,这是任何指针概念中指针的整个工作格式的一部分。
  • 获取锁和 weak_ptr 的行为指向使终端资源被释放,并由 weak_ptr 释放,然后 shared_ptr 与释放使其使用。
  • 一旦所有提到的资源被释放,那么列表和它的相关节点也会被轻易地销毁和区分,从而使分析和格式化的优化方式。
  • 有许多测试和方法是整个周期的一部分,包括expired()方法,它用于测试所有权是否已经过期。
  • Lock()用于获得对资源的独占和单独的锁,这样其他资源在试图获取资源时就不能成为目标并产生冲突。
  • owner()用于测试 weak_ptr 的指向,如果它指向正确,则返回 true。
  • Reset()用于在整个周期内释放拥有的资源。
  • 当两个 weak_ptr 作用于对象时,那么它被称为 swap() 方法。
  • use_count()方法用于计算和跟踪共享_ptr对象的数量。
  • Operator= 是用于替换最初拥有的资源的方法。

C++ weak_ptr 的例子

下面是C++ weak_ptr的例子。

例子 #1

这个程序演示了将 weak_ptr 用作一个构造函数,其中作为构造函数传递的参数被用来获取锁并给出相应的值,如输出中所示。

代码

#include <memory>
#include <iostream>
int main()
{
std::weak_ptr<int> wptr_0;
std::cout << "weak_ptr got expired " << std::boolalpha
<< wptr_0.expired() << std::endl;
std::shared_ptr<int> shrd_ptr1(new int(12));
std::weak_ptr<int> wptr_1(shrd_ptr1);
std::cout << "*wptr_1 acquired the_lock() == "
<< *wptr_1.lock() << std::endl;
std::weak_ptr<int> wptr_2(wptr_1);
std::cout << "*wptr_2 acquired the_lock() == "
<< *wptr_2.lock() << std::endl;
return (0);
}

输出

C++ weak_ptr output 1

示例 #2

这个程序演示了方法 owner_before,在 weak_ptr 的帮助下,明确地讲述了使用布尔值获取的值,然后像之前那样重置值,并给出了输出中所示的输出。

代码

#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> shrd_ptr(new int(14));
std::weak_ptr<int> wk_ptr(shrd_ptr);
std::cout << "acquire weak_ptr in the lock: == " << *wk_ptr.lock() << std::endl;
std::cout << "weak_ptr got expired == " << std::boolalpha
<< wk_ptr.expired() << std::endl;
wk_ptr.reset();
std::cout << "After reset weak ptr fot expired*wk_ptr.lock()() == " << std::boolalpha
<< wk_ptr.expired() << std::endl;
return (0);
}

输出

C++ weak_ptr output 2

例子 #3

这个程序演示了用于管理要访问的元素的顺序的weak_ptr的数量,如输出中所示。

代码

#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> shrd_ptr_1(new int(8));
std::weak_ptr<int> wk_ptr(shrd_ptr_1);
std::cout << "count the numner_of_weak_ptr : "
<< wk_ptr.use_count() << std::endl;
std::shared_ptr<int> shrd_ptr_2(shrd_ptr_1);
std::cout << "count the number_of_weak_ptr : "
<< wk_ptr.use_count() << std::endl;
return (0);
}

输出

C++ weak_ptr output 3

例子 #4

这个程序演示了swap()方法,当需要获取所需的资源时,用于交换weak_ptr,如输出中所示。

代码

#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> shrd_ptr_1(new int(8));
std::shared_ptr<int> shrd_ptr_2(new int(10));
std::cout << "*shrd_ptr_1 == " << *shrd_ptr_1 << std::endl;
shrd_ptr_1.swap(shrd_ptr_2);
std::cout << "*shrd_ptr_1 == " << *shrd_ptr_1 << std::endl;
swap(shrd_ptr_1, shrd_ptr_2);
std::cout << "*shrd_ptr_1 == " << *shrd_ptr_1 << std::endl;
std::cout << std::endl;
std::weak_ptr<int> wk_ptr_1(shrd_ptr_1);
std::weak_ptr<int> wk_ptr_2(shrd_ptr_2);
std::cout << "*wk_ptr_1 == " << *wk_ptr_1.lock() << std::endl;
wk_ptr_1.swap(wk_ptr_2);
std::cout << "*wk_ptr_2 == " << *wk_ptr_2.lock() << std::endl;
swap(wk_ptr_1, wk_ptr_2);
std::cout << "*wk_ptr_1 == " << *wk_ptr_1.lock() << std::endl;
return (0);
}

输出

output 4

结论

C++ weak_ptr 在获取和访问列表节点内的元素方面起着关键的作用。同时,shared_ptr 与 weak_ptr 相互协调,有助于创建一个优化的循环来访问元素。一旦 shared_ptr 被选择,那么它就被认为是一个永久的操作。C++ weak_ptr在许多方面有助于有效地获取资源。