C++智能指针weak_ptr

C++ 智能指针unique_ptr、shared_ptr、weak_ptr详解(包含代码示例) 阅读详情
AI摘要

本文介绍了C++11引入的智能指针weak_ptr,它通常与其他智能指针配合,用于解决循环引用问题。weak_ptr是弱引用,不增加对象引用计数,不控制生命周期。文中阐述了其基本特点、用法,包括创建、获取、检查过期等,还通过实例说明其解决循环引用的作用,并提及注意事项。

weak_ptr 是 C++11 引入的智能指针之一,通常与 shared_ptr 配合使用,用于解决 shared_ptr 可能出现的循环引用问题。


一、什么是 weak_ptr

weak_ptr 是一种“弱引用”智能指针,它不会增加所管理对象的引用计数。它的主要作用是用来观察或访问由 shared_ptr 管理的资源,而不拥有该资源的所有权。由于不拥有所有权,weak_ptr 指向的对象可能在某些情况下已经被销毁,因此在使用时需要特别小心。


二、基本特点

  1. 不控制生命周期:weak_ptr 不会影响对象的引用计数,因此不会阻止对象被销毁。
  2. 依赖 shared_ptr:weak_ptr 必须从一个 shared_ptr 或另一个 weak_ptr 创建。
  3. 解决循环引用:当两个对象通过 shared_ptr 互相引用时,会导致内存泄漏。使用 weak_ptr 可以打破这种循环。
  4. 需要检查有效性:由于 weak_ptr 指向的对象可能已经被销毁,使用前需要通过 lock() 方法转换为 shared_ptr 并检查是否有效。

三、基本用法

以下是 weak_ptr 的常见用法及其代码示例:

1. 创建 weak_ptr

weak_ptr 通常从 shared_ptr 初始化:

#include <iostream>
#include <memory>

int main() {
    std::shared_ptr<int> sp = std::make_shared<int>(42);
    std::weak_ptr<int> wp = sp; // 从 shared_ptr 创建 weak_ptr

    std::cout << "shared_ptr use_count: " << sp.use_count() << std::endl; // 输出 1
    return 0;
}
  • wp 是从 sp 创建的弱引用。
  • sp.use_count() 返回 1,因为 weak_ptr 不增加引用计数。

2. 使用 lock() 获取 shared_ptr

在使用 weak_ptr 访问对象之前,必须通过 lock() 将其转换为 shared_ptr,并检查是否有效:

#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 = wp.lock()) { // 尝试获取 shared_ptr
        std::cout << "Value: " << *locked << std::endl; // 输出 42
        std::cout << "use_count: " << locked.use_count() << std::endl; // 输出 2
    } else {
        std::cout << "Object has been destroyed" << std::endl;
    }

    sp.reset(); // 释放 shared_ptr
    if (auto locked = wp.lock()) {
        std::cout << "Value: " << *locked << std::endl;
    } else {
        std::cout << "Object has been destroyed" << std::endl; // 输出此行
    }

    return 0;
}
  • lock() 返回一个 shared_ptr,如果对象仍存在则有效,否则返回空指针。
  • 当 sp 被销毁后,wp.lock() 返回空指针,表示资源已不可用。

3. 检查是否过期

可以用 expired() 方法检查 weak_ptr 是否指向已销毁的对象:

#include <iostream>
#include <memory>

int main() {
    std::weak_ptr<int> wp;
    {
        std::shared_ptr<int> sp = std::make_shared<int>(42);
        wp = sp;
        std::cout << "Expired? " << wp.expired() << std::endl; // 输出 0 (false)
    }
    std::cout << "Expired? " << wp.expired() << std::endl; // 输出 1 (true)
    return 0;
}
  • expired() 返回 true 表示对象已销毁,false 表示仍有效。

四、解决循环引用问题

weak_ptr 的核心应用场景是打破 shared_ptr 的循环引用。以下是一个经典例子:

循环引用问题

#include <iostream>
#include <memory>

struct Node {
    std::shared_ptr<Node> next;
    ~Node() { std::cout << "Node destroyed" << std::endl; }
};

int main() {
    auto node1 = std::make_shared<Node>();
    auto node2 = std::make_shared<Node>();
    node1->next = node2;
    node2->next = node1; // 循环引用
    std::cout << "End of main" << std::endl;
    return 0;
}
  • 输出只有 “End of main”,Node 的析构函数未被调用,因为 node1 和 node2 互相持有对方的 shared_ptr,引用计数无法降到 0。

使用 weak_ptr 解决问题

#include <memory>
#include <iostream>

struct Node{
    std::weak_ptr<Node> next;
    ~Node(){
        std::cout << "Node deleted" << std::endl;
    }
};

int main() {
    std::weak_ptr<Node> wp1,wp2;
    {
        auto node1 = std::make_shared<Node>();
        auto node2 = std::make_shared<Node>();
        node1->next = node2;
        node2->next = node1;
        wp1 = node1;
        wp2 = node2;
        std::cout << node1.use_count() <<"," << node2.use_count() << std::endl;
    }
    std::cout << wp1.use_count() <<"," << wp2.use_count() << std::endl;

    std::cout << "End of main " << std::endl;
    return 0;
}
  • 输出:
      1,1
      Node deleted
      Node deleted
      0,0
      End of main
    
  • 使用 weak_ptr 后,循环引用被打破,对象能正常销毁。

五、注意事项

  1. 不能直接解引用:weak_ptr 没有 operator* 或 operator->,必须通过 lock() 转换为 shared_ptr。
  2. 线程安全:weak_ptr 的 lock() 操作是线程安全的,但对其本身的赋值或构造不是。
  3. 性能开销:weak_ptr 的使用会引入少量开销(如检查有效性),但在需要避免循环引用时是值得的。

六、总结

  • 用途:weak_ptr 主要用于观察资源或打破 shared_ptr 的循环引用。
  • 关键方法:lock() 获取 shared_ptr,expired() 检查有效性。
  • 典型场景:对象间存在潜在循环引用(如链表、树结构)时。
【C++11】weak_ptr智能指针使用详解 在C++编程中,处理循环引用是一个常见的问题。循环引用可能导致内存泄漏和资源管理问题。为了解决这个问题,C++11引入了weak_ptr智能指针。弱指针(weak_ptr)是一种不受控制所指向对象生存期的智能指针,它指向由一个shared_ptr管理的对象。允许你共享对象的所有权,但不会增加对象的引用计数。它是一种弱引用,不会阻止对象的销毁。一旦一个指向对象的shared_ptr被销毁,对象就会被释放。即使有weak_ptr指向对象,对象也会被释放。 阅读详情

相关推荐

C++ weak_ptr 详解:从原理到实战,彻底解决shared_ptr循环引用

weak_ptr不是独立的智能指针,而是shared_ptr的“辅助工具”,用于解决循环引用和安全观察对象。2. 核心特性:不拥有对象、不增加强引用计数、需升级为shared_ptr才能访问对象、线程安全的lock()接口。3. 核心场景:解决shared_ptr循环引用、缓存、观察者模式。掌握weak_ptr,能让你在使用shared_ptr时更安全、更灵活,彻底摆脱循环引用导致的内存泄漏问题,写出更健壮的C++代码。最后,留一个小练习:尝试用weak_ptr。

W2303576573的博客 580

C++智能指针weak_ptr详解

一、背景 weak_ptr这个指针天生一副“小弟”的模样,也是在C++11的时候引入的标准库,它的出现完全是为了弥补它老大shared_ptr天生有缺陷的问题,其实相比于上一代的智能指针auto_ptr来说,新进老大shared_ptr可以说近乎完美,但是通过引用计数实现的它,虽然解决了指针独占的问题,但也引来了引用成环的问题,这种问题靠它自己是没办法解决的,所以在C++11的时候将shared_ptr和weak_ptr一起引入了标准库,用来解决循环引用的问题。 二、使用方法 std::weak_pt

sinat_31608641的博客 2万+

C++总结8——shared_ptr和weak_ptr智能指针

智能指针的提出:智能指针是存储指向动态分配对象指针的类,用于生存期控制。能够确保正确销毁动态分配的内存,防止内存泄露。 1.智能指针的分类: 不带引用计数的智能指针 auto_ptr unique_ptr scoped_ptr 带引用计数的智能指针 shared_ptr:强智能指针 weak_ptr:若智能指针

wendy_keeping的博客 1191

weak_ptr

weak_ptr是为了配合shared_ptr而引入的一种智能指针,它指向一个由shared_ptr管理的对象而不影响所指对象的生命周期,即就是将一个weak_ptr绑定到shared_ptr不会改变shared_ptr的引用计数。不论是否有用weak_ptr指向一旦最后一个指向对象的shared_ptr被销毁,对象就会是释放。从这个角度看,weak_ptr更像是一个shared_ptr的助手,weak_ptr并不拥有对对象的管辖权,weak_ptr指向shared_ptr的目标也不会增加计数器值。

m0_57719144的博客 4366

C++智能指针--weak_ptr

weak_ptr是对对象的一种弱引用,它不会增加对象的引用计数。weak_ptr和shared_ptr之间可以相互转换,shared_ptr可以直接赋值给week_ptr,week_ptr可通过调用lock函数来获得shared_ptr(如果对象已经被释放,则返回一个空的shared_ptr)。     单纯使用shared_ptr有时会产生问题,考虑下面的代码: 1 class

鱼思故渊的专栏 2430

C++智能指针详解[shared_ptr、unique_ptr、weak_ptr]]

C++智能指针、shared_ptr、unique_ptr、weak_ptr详解

qq_44237695的博客 1260

【C++】weak_ptr弱引用智能指针详解

weak_ptr这个指针天生一副小弟的模样,也是在C++11的时候引入的标准库,它的出现完全是为了弥补它老大shared_ptr天生有缺陷的问题。 相比于上一代的智能指针auto_ptr来说,新进老大shared_ptr可以说近乎完美,但是通过引用计数实现的它,虽然解决了指针独占的问题,但也引来了引用成环的问题,这种问题靠它自己是没办法解决的,所以在C++11的时候将shared_ptr和weak...

Yngz_Miao的博客 3万+

C++11 weak_ptr智能指针详解

weak_ptr这个指针天生一副“小弟”的模样,也是在C++11的时候引入的标准库,它的出现完全是为了弥补它老大shared_ptr天生有缺陷的问题,其实相比于上一代的智能指针auto_ptr来说,新进老大shared_ptr可以说近乎完美,但是通过引用计数实现的它,虽然解决了指针独占的问题,但也引来了引用成环的问题,这种问题靠它自己是没办法解决的,所以在C++11的时候将shared_ptr和weak_ptr一起引入了标准库,用来解决循环引用的问题。weak_ptr本身也是一个模板类,但是不能直接用它来定

二进制君 5276

C++11的智能指针shared_ptr、weak_ptr源码解析

C++智能指针shared_ptr源码解析1、前言2、源码准备3、智能指针概念4、源码解析4.1、shared_ptr解析4.1.1、shared_ptr4.1.2、__shared_ptr4.1.3、__shared_count4.1.4、_Sp_counted_base4.1.5、_Sp_counted_ptr 1、前言 本文仅对C++智能指针shared_ptr、weak_ptr源码进行解析,需要读者有一定的C++基础并且对智能指针有所了解,但是本文不对智能指针的使用方法、使用场景、效率等方面进行阐述

游戏行业资深搬砖人员 1万+

别再折腾框架了!用华为应用市场官方渠道搞定GBOX,安全安装谷歌全家桶(鸿蒙HarmonyOS 3/4实测)

本文详细介绍了如何在鸿蒙系统上通过华为应用市场官方渠道安全安装GBOX,实现谷歌全家桶的无损使用。该方法避免了传统破解方式的安全风险,利用沙箱技术隔离运行环境,确保系统稳定性和数据安全。特别适合鸿蒙HarmonyOS 3/4用户安全使用谷歌生态应用。

weixin_29305313的博客 4744

【万字长文】学习Armv8架构虚拟化一篇就够了

这里我们将介绍一些基础的Hypervisor和虚拟化的理论知识。如果你已经有一定的基础或是已经熟悉了这些概念,可以跳过这部分内容。我们用Hypervisor这个词来定义一种负责创建,管理以及调度虚拟机(Virtual Machines, VMs)的软件。Stage 2 转换允许Hypervisor控制虚拟机的内存视图。具体来说,其可以控制虚拟机是否可以访问特定的某一块物理内存,以及该内存块出现在虚拟机内存空间的位置。这种能力对于虚拟机的隔离和沙箱功能来说至关重要。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 5312

C++14 智能指针unique_ptr、shared_ptr、weak_ptr

内存控制这一大毒瘤,几乎一致伴随着C/C++工程师。随着计算机技术的发展,在boost准标准库的推动下,C++11终于将unique_ptr、shared_ptr、weak_ptr这几类智能指针纳入C++中。当然,在这之前还有一种auto_ptr智能指针,不过由于它的设计存在较大问题(比如:auto_ptr与STL不兼容),现阶段已经很少能看到它的出现了。

机器学习 1万+

硬核干货|C#+EtherCAT协议:高精度多轴伺服运动控制通信实战

本文摘要: 文章聚焦工业自动化领域多轴伺服运动控制的高精度与实时性需求,基于C#与EtherCAT协议实现完整解决方案。EtherCAT凭借微秒级同步、分布式架构等优势成为首选,而C#通过优化GC策略和实时线程可满足工业控制要求。文章从工程落地角度,详细拆解EtherCAT的PDO/SDO通信机制与多轴同步控制逻辑,提供完整的C#代码实现(主站初始化、伺服配置、运动控制等),所有代码均通过汇川/松下伺服实测验证。核心亮点包括:纯C#原生开发、工业现场高频问题解决方案、硬件适配指南,帮助开发者快速掌握高精度多

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 575

C++智能指针之weak_ptr

C++智能指针之weak_ptr

ERAtime的博客 921

海上风电经柔性直流送出系统的阻抗建模与稳定性分析

摘要 本文针对海上风电经柔性直流送出系统的稳定性问题,提出了一种基于阻抗建模的分析方法。研究建立了直驱永磁同步发电机(PMSG)的序阻抗解析模型和模块化多电平换流器(MMC)的交流侧小信号阻抗模型,通过Matlab/Simulink平台实现了完整的仿真验证系统。采用谐波线性化原理和端口阻抗分析法,揭示了风电机组与柔直换流器之间的阻抗匹配特性对系统稳定性的影响规律。研究结果表明,控制参数设置会显著改变系统阻抗特性,进而影响稳定裕度。文中提出的阻抗建模方法为分析海上风电柔直送出系统的宽频振荡问题提供了有效工具,

huanghm88的专栏 231

SpringBoot实现快速导入EXCEL

MaterialMonitorController.java @Log(title = "物料监测", businessType = BusinessType.IMPORT) @RequiresPermissions("system:materialMonitor:import") @PostMapping("/importData") @ResponseBody ...

LEN程序员的一生 4816

C++_智能指针shared_ptr和weak_ptr

智能指针的本质是一个模板类,内部封装了指针变量和一些方法. 智能指针的原理是创建一个模板类对象并将其压入栈中,然后将new申请的堆内存指针(原始指针)"委托"给智能指针,当智能指针超出其作用域要释放时,系统自动调用智能指针的析构函数(内部有释放原始指针的一系列代码),从而将原始指针指向的内存自动释放,不再需要程序员手动释放,极大地减少了内存泄漏和野指针的问题,很nice.

qq_74224788的博客 1924

7、刚度矩阵与弹簧元素:有限元分析的核心

本文深入探讨了有限元分析中的核心概念——刚度矩阵与弹簧元素。详细介绍了刚度矩阵的定义、构建方法及其对称性、正定性和稀疏性等性质,同时解析了弹簧和阻尼器元素的特性及其在模拟复杂系统中的应用,如液压缸、减震器等。通过结合刚度矩阵与弹簧元素,可以提高结构模型的精度并模拟复杂的工程系统。文章还讨论了优化策略、验证流程、误差分析及实际应用案例,展示了这些技术在桥梁分析、汽车悬挂系统等领域的重要作用,并展望了其在未来新材料、智能结构和数字孪生技术中的发展潜力。

nice1的博客 233

C++智能指针的使用,auto_ptr,unique_ptr,shared_ptr,weak_ptr详解

C++智能指针的用法,auto_ptr,unique_ptr,shared_ptr,weak_ptr

liu20000505的博客 2312

【UVM实战】第一章:配置UVM环境(以VCS为例),跑通书上的例子(包括清理中间文件方法、使用DVE查看波形方法、命令执行原理探究)

如何配置UVM的VCS运行环境,运行书本上的例子呢?本节将会为你详细解答!

悟已往之不谏 知来者之可追 8131

(6):单相三绕组变压器的拉氏变换数学模型和仿真模型

本节详细推导了基于耦合电路的单相三绕组变压器考虑铁心损耗情况下的拉普拉斯变换数学模型,并据此用Matlab/Simulink的传递函数模块搭建了相应的仿真模型,仿真结果表明所建立的数学模型和仿真模型都是正确的。本文的贡献是建立了考虑铁心损耗的单相三绕组变压器基于拉氏变换象函数的数学模型,为使用Simulink传递函数模块实现单相三绕组变压器的仿真模型提供了一条途径,所采用的建模方法和技巧具有启发作用,值得借鉴。

weixin_45670943的博客 372

C++ 智能指针的原理:auto_ptr、unique_ptr、shared_ptr、weak_ptr

介绍C++的智能指针:auto_ptr、unique_ptr、shared_ptr、weak_ptr。介绍了每种智能指针的作用和特点,以及它们的实现原理,同时介绍了shared_ptr的循环引用的问题,以及如何解决循环引用。

weixin_57761086的博客 2522

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

C++智能指针auto_ptr、unique_ptr、shared_ptr、weak_prt详解

C++智能指针auto_ptr、unique_ptr、shared_ptr、weak_prt详解

GodFishhh的博客 2467

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C++智能指针 shared_ptr,unique_ptr和weak_ptr

1.智能指针为什么存在?因为C++没有自动回收内存的机制,因此每一次new出来的动态内存必须手动delete回去。因此智能指针可以解决这个问题。2.智能指针的大致描述是什么?智能指针:自动负责释放所指向的对象,实际上它利用了栈的机制,每一个智能指针都是一个模板类,调用智能指针实际上是创建了一个智能指针的对象,对象生命周期到达尽头的时候,会自动调用智能指针的析构函数,在析构函数里,释放掉它管理的内存,

zhuziyu1157817544 1万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C++智能指针:unique_ptr、shared_ptr、weak_ptr

shared_ptr:允许多个指针指向同一个对象 unique_ptr:独占所指向的对象 weak_ptr:弱引用,指向shared_ptr所管理的对象。可以有效解决循环引用的问题

倒地不起的土豆 1462

C++11智能指针之weak_ptr

文章目录前言,接上节:Weak_Ptr创建现在让我们见识一下`weak_ptr`如何解决循环引用问题: 前言,接上节: 为了解决循环引用,C++提供了另外一种智能指针:weak_ptr Weak_Ptr weak_ptr 拥有共享语义(sharing semantics)和不包含语义(not owning semantics)。这意味着,weak_ptr可以共享shared_ptr持有的资源。所以可以从一个包含资源的shared_ptr创建weak_ptr。 weak_ptr不支持普通指针包含的*,-&gt

创造晴天 803
上一篇: C++智能指针shared_ptr
下一篇: C++智能指针unique_ptr
卖猪肉的痴汉
博客等级 码龄10年 166粉丝 82原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值