【c++11】测试 : weakptr

本文主要介绍了C++11中weak_ptr的使用,包括通过weak_ptr获取shared_ptr,当shared_ptr被reset后,weak_ptr的lock将返回空。同时,weak_ptr可以作为函数参数传递,不会增加引用计数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 创建sharedptr 对象 SPTR, 赋值给WPTR :
  • home::WPtr shandong = feicheng;
  • 从 WPTR 获取sharedptr 对象:
  • auto strongHome = shandong.lock();
  • 传递weakptr作为形参

测试代码

#include <iostream>
#include <memory>

class home //: public enable_shared_from_this
{
   
   
### C++ `weak_ptr` 的用法与示例 #### 什么是 `weak_ptr` `std::weak_ptr` 是一种不控制对象生命周期的智能指针。它通常用于配合 `std::shared_ptr` 使用,以打破循环引用并避免内存泄漏。由于 `weak_ptr` 不增加所指向对象的引用计数,因此不会阻止该对象被销毁。 当通过 `lock()` 方法尝试访问由 `weak_ptr` 所管理的对象时,如果对象仍然存在,则返回一个有效的 `shared_ptr`;否则返回一个空的 `shared_ptr`[^1]。 --- #### 基本语法 以下是创建和使用 `weak_ptr` 的基本方法: ```cpp #include <iostream> #include <memory> int main() { std::shared_ptr<int> sp = std::make_shared<int>(42); std::weak_ptr<int> wp = sp; if (auto locked_sp = wp.lock()) { // 尝试锁定 weak_ptr std::cout << "Value: " << *locked_sp << "\n"; } else { std::cout << "Object no longer exists.\n"; } sp.reset(); // 销毁共享资源 if (wp.expired()) { // 检查资源是否已释放 std::cout << "Resource has been released.\n"; } } ``` 在这个例子中: - 创建了一个 `shared_ptr` 并将其赋值给 `weak_ptr`。 - 调用了 `wp.lock()` 来获取一个临时的 `shared_ptr` 实例。 - 当原始 `shared_ptr` 被重置后,调用 `wp.expired()` 可以确认资源已被释放[^1]。 --- #### 解决弱指针相关问题 ##### 场景一:防止循环引用 在某些情况下,两个或多个对象可能相互持有对方的 `shared_ptr`,从而形成循环引用。这会导致这些对象永远不会被销毁。此时可以引入 `weak_ptr` 来破坏这种依赖关系。 ```cpp struct Node; typedef std::shared_ptr<Node> NodePtr; struct Node { int value; NodePtr next; // Strong reference to the next node. std::weak_ptr<Node> prev; // Weak reference to the previous node. explicit Node(int val) : value(val), next(nullptr) {} }; void setNext(NodePtr& current, NodePtr&& newNode) { if (current && newNode) { newNode->prev = current; // Store a weak pointer to 'current'. current->next = std::move(newNode); // Update strong pointer of 'current'. } } // Example usage: int main() { auto head = std::make_shared<Node>(10); auto tail = std::make_shared<Node>(20); setNext(head, std::move(tail)); if (head->next && !head->next->prev.expired()) { std::cout << "Head's next is valid and points back correctly.\n"; } } ``` 在此场景下,节点之间的双向链接通过 `weak_ptr` 和 `shared_ptr` 组合实现,有效避免了循环引用的发生[^1]。 --- ##### 场景二:延迟加载数据结构中的子项 假设有一个复杂的数据结构(如树形结构),其中父节点需要动态加载其子节点的内容。为了避免提前分配不必要的内存,可以在实际需要之前仅存储子节点的 `weak_ptr`。 ```cpp #include <map> #include <string> #include <memory> class TreeNode { public: std::string name; std::map<std::string, std::weak_ptr<TreeNode>> children; explicit TreeNode(const std::string& n) : name(n) {} void addChild(const std::string& childName, const std::shared_ptr<TreeNode>& child) { children[childName] = child; } bool loadChild(const std::string& childName) { auto it = children.find(childName); if (it != children.end()) { if (auto loaded_child = it->second.lock()) { std::cout << "Loaded existing child '" << loaded_child->name << "'\n"; return true; } } return false; } }; ``` 此代码片段展示了如何利用 `weak_ptr` 存储潜在未初始化的孩子节点,并在必要时重新构建它们的强引用。 --- #### 总结 `weak_ptr` 提供了一种灵活的方式来观察其他 `shared_ptr` 管理的对象状态,而无需影响其生存周期。它的主要用途包括但不限于: - 避免循环引用引起的内存泄露; - 在缓存机制中跟踪外部资源的存在与否; - 动态加载大型数据集的部分内容。 尽管如此,在设计程序逻辑时仍需谨慎考虑何时以及为何选用 `weak_ptr`,因为不当使用可能导致运行期错误或者性能瓶颈。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等风来不如迎风去

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值