[C++11] 循环引用

2023-05-16

前言

虽然C++11中的智能指针,一定程度上简化了C++当中的内存管理;但是,shared_ptr<>的使用同时也引出了另一个问题:循环引用

例子

让我们先来看一段示例代码。

#include <iostream>
#include <vector>
#include <memory>

using namespace std;

class parent;
class children;

class parent {
public:
    ~parent() { std::cout << "~parent()" << std::endl; }

public:
    std::shared_ptr<children> child;
};

class children {
public:
    ~children() { std::cout << "~children()" << std::endl; }

public:
    std::shared_ptr<parent> parent;
};

void Verify() {
    std::shared_ptr<parent> p(new parent);
    std::shared_ptr<children> c(new children);

    p->child = c;
    c->parent = p;
}

int main() {
    std::cout << "Begin" << std::endl;

    Verify();

    std::cout << "Done" << std::endl;
}

运行之后,我们可以发现两个对象都没有被正常析构。
在这里插入图片描述

分析

当我们想要parent对象释放时,children对象中仍保留了该parent对象的shared_ptr,导致其无法被正常释放。既然是因为children对象保留了引用,那么就先释放children对象呗?很好,parent对象中保留了该children对象的shared_ptr。这样,我们就陷入了一个死循环:循环引用。

解决办法

1. 手动打破"循环引用"

void Verify() {
    std::shared_ptr<parent> p(new parent);
    std::shared_ptr<children> c(new children);

    p->child = c;
    c->parent = p;

    p->child.reset();	// let it go,手动打破“循环引用”这种尴尬的局面;
}

2. 使用weak_ptr

weak_ptr仅保持对对象的引用,而不负责具体的资源管理;
但是,相比裸指针而言,weak_ptr提供了expired()接口,方便检测引用的对象是否已经释放,这点是裸指针所不具备的。

class parent {
public:
    ~parent() { std::cout << "~parent()" << std::endl; }

public:
    std::shared_ptr<children> child;
};

class children {
public:
    ~children() { std::cout << "~children()" << std::endl; }

public:
    std::weak_ptr<parent> parent;	// 替换成“弱引用”
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[C++11] 循环引用 的相关文章

  • Threejs性能监视和可视化控制

    概述 性能监视是监视threejs运行中的刷新频率 xff0c 要使用到threejs提供的stat js xff0c 可视化控制是在窗口中显示一个可见的控制框 xff0c 可以通过鼠标改变其中的值 xff0c 达到改变threejs对象参
  • threejs加载3D模型例子

    加载3D模型 首先要引入ColladaLoader加载器 xff0c Collada是一个3D模型交换方案 xff0c 即不同的3D模型可以通过Collada进行相互转换 xff0c 言外之意 xff0c threejs可以使用Collad
  • threejs坐标转换

    屏幕坐标转three js坐标 将屏幕坐标转变成threejs空间坐标 xff1a span class hljs function span class hljs keyword function span span class hljs
  • 搭建GitLab+Jenkins持续集成环境图文教程

    GitLab是一个代码仓库 xff0c 用来管理代码 Jenkins是一个自动化服务器 xff0c 可以运行各种自动化构建 测试或部署任务 所以这两者结合起来 xff0c 就可以实现开发者提交代码到GitLab xff0c Jenkins以
  • threejs-经纬度转换成xyz坐标的方法

    用threejs做3D应用时 xff0c 很经常会接触到球状物体 xff0c 比如说地球 xff0c 要定义球上的一点 xff0c 用经纬度是常用的办法 现在 xff0c 我们要在北京这个地方标一个点 xff0c 北京的坐标为 北纬39 9
  • HTML5 响应式图片

    现在上网设备越来越多 xff0c 各种设备的屏幕千差万别 xff0c 如果只用一张图片去涵盖所有的设备 xff0c 一是可能会造成某些设备上显示效果不佳 xff0c 比如使用了一张低清晰度的图 xff0c 而网页运行在一个高清大屏里 xff
  • 使用EventBus通讯不成功

    最近在开发一个直播app的项目 xff0c 遇到一个需求是当用户点击 退出登录 这个操作时 xff0c 回到登录界面 xff0c 让用户重新登录 这个需求实现起来一点都不难 xff0c 不就是点击退出登录后 xff0c Intent到Log
  • 怎么使用CTreeListCtrl

    代码路径 xff1a http www codeproject com KB tree ctreelistctrl aspx 1 怎么在CTreeListCtrl中使用edit或者combobox 例如双击修改某个item 重载OnLBut
  • android backtrace实现

    前景 backtrace 文档 说明 通过数组获取调用栈 一般获取的是内存地址 借助dladdr获取地址信息 计算可执行文件中的偏移地址 实现 有的没有实现backtrace但是大多都支持unwind 利用unwind实现类似 backtr
  • 【详细教程】阿里云ECS服务器搭建

    一 服务器搭建的网址入口 xff1a 如果您之前没有用过 xff0c 恭喜您 xff0c 是有试用资格的 有试用资格 xff1a 点击进入阿里云云产品试用中心 xff0c 选择下图产品 xff0c 点击试用30天 如果未注册 xff0c 需
  • Matlab绘图-详细,全面(二维&三维等)

    原文 Matlab绘图 xff08 图像为本人所绘 xff09 强大的绘图功能是Matlab的特点之一 xff0c Matlab提供了一系列的绘图函数 xff0c 用户不需要过多的考虑绘图的细节 xff0c 只需要给出一些基本参数就能得到所
  • SpotBugs-IDE插件扫描

    安装 在 Intellij IDE 的Plugins中搜索 SpotBugs 并 安装 设置 打开IDE Settings xff0c 选择 Tools SpotBugs 根据实际情况进行配置 比如选择分析投入 xff0c 分析等级 xff
  • 【C语言】vsnprintf函数的使用

    标题 C语言 vsnprintf函数的使用 提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 标题 C语言 vsnprintf函数的使用前言一 vsnprintf是什么 xff1
  • [python]编写程序产生 ISBN 号的校验位。

    64 MADE BY YWL XJTU python编写程序产生 ISBN 号的校验位 编写程序产生 ISBN 号的校验位 任何新出版的图书都配有 ISBN 号 xff0c 2007 年以前是由 10 位数字加上3个连字符组成的 ISBN
  • python基于内置模块smtplib、email实现163邮箱发送邮件(附完整代码,可直接使用)

    一 获取发送者163邮箱授权密码 第一步 登录邮箱 https mail 163 com 第二步 点击右上角切换回旧版 新版实在没找到在哪 第三步 打开 POP3 SMTP IMAP 设置 第四步 开启POP3 SMTP 服务 第五步 拿到
  • 极速配置VScode C++运行环境

    VScode 极速配置C 43 43 环境及必备插件 Visual Studio Code 简称 VS Code VSC 是一款免费开源的现代化轻量级代码编辑器 xff0c 支持几乎所有主流的开发语言的语法高亮 智能代码补全 自定义热键 括
  • 题目49:输入两个正整数 m 和 k,其中1 < m < 100000,1 < k < 5 ,判断 m 能否被19整除,且恰好含有k个3,如果满足条件,则输出YES,否则,输出NO。

    题目转载 xff1a http python wzms com s 1 42 题目描述 输入两个正整数 m 和 k xff0c 其中1 lt m lt 100000 xff0c 1 lt k lt 5 xff0c 判断 m 能否被19整除
  • Linux 监控网络流量

    文章目录 bmoniftopnethogs bmon sudo apt get install bmon 通过 选择网卡 xff1b 输入 g 控制流量面板的显示和隐藏 xff1b 输入 d 控制详情信息的显示和隐藏 xff1b 输入 q
  • CentOS7.2 在GUI下关闭X Server

    有时候需要关闭X Server xff0c 例如在安装NVIDIA驱动的时候 xff0c 需要关闭X Server xff0c 我们可以通过服务来关闭 首先看下服务 root span class hljs variable 64 soft
  • 用c语言实现 将src指向的字符串追加到dest指向字符串的后面

    实现char my strcat char dest char src 函数 返回 xff1a dest字符串的地址 功能 xff1a 将src指向的字符串追加到dest指向字符串的后面 例如 xff1a char dest 10 61 3

随机推荐

  • CoreData 实体之间的关系

    1 Cascade 级联关系 2 Deny 禁止 3 Nullify 作废 当实体之间创建了关系的时候 xff0c 我们需要判断是否建立级联关系 例如 人和身份证是一对一的 两者之间关系反转 即 人有身份证 xff0c 身份证包含人 当删除
  • Doris入门篇-分区分桶实验

    简介 测试分区分桶效果 分区的基本操作 添加分区 ALTER TABLE v2x olap database government car ADD PARTITION p20221203 VALUES LESS THAN 34 2022 1
  • PostgreSQL中的json解析

    1 PostgreSQL json 数组解析 span class token comment INSERT INTO 34 dwd 34 34 dwd test 34 id cname is deleted span span class
  • ceph集群搭建

    ceph集群搭建 文章目录 ceph集群搭建cephceph的构成搭建ceph集群实现块存储客户端使用块设备 ceph ceph被称作面向未来的存储 中文手册 xff1a https access redhat com documentat
  • Pycharm双击没反应,或者No JVM installation found.或者Could not find main class com/intelljj/idea/Main问题解决

    Pycharm双击没反应 xff0c 或者No JVM installation found 或者Could not find main class com intelljj idea Main根源之一在于破解没有成功 找到如下路劲 xff
  • 实验 详解MHA搭建过程中的遇到的各种问题

    实验 详解MHA搭建过程中的遇到的各种问题 一 MHA搭建过程中问题集合问题一 xff1a 问题二 xff1a 问题三 xff1a 问题四 xff1a 问题五 xff1a 问题六 xff1a 问题七 xff1a 问题八 xff1a 问题九
  • 【软件】使用docker尝试解决CUDA的版本与显卡不匹配

    1 CUDA的版本与显卡不匹配 参考 xff1a knavMVSNet代码复现问题解决 cuBlas call failed status 61 13问题 KyrieLiu52的博客 CSDN博客 解决方案 xff1a 1 xff09 更换
  • STM32 HAL库函数学习 I2C篇

    本篇内容讲述STM32的硬件IIC功能 硬件IIC的使用在F1系列上可能会有问题 本次使用的测试平台是H7 xff0c 用于AT24C02芯片的读写正常 xff0c 暂不清楚在其他芯片上使用是否正常 1 HAL StatusTypeDef
  • C++ 第二章 类和对象

    C 43 43 第二章 类和对象 类 c 43 43 新增了对象这个功能 xff0c 不仅有数据 xff0c 而且可以对数据进行操作的函数 Class span class token class name A span span clas
  • Apache站点中文乱码解决方案

    1 编辑apache配置文件修改以下内容 vim etc httpd conf httpd conf 查找AddDefaultCharset字段 将UTF 8修改为GBK或者GB2312重启httpd服务后 xff0c 中文显示正常 2 将
  • bat中调用vs

    https blog csdn net lixiangminghate article details 51350846
  • less文件中导入另一个less文件

    有一个common less文件 根据媒体查询 span class token punctuation span 设置不同屏幕中的html字号 屏幕划分为15等份 默认显示html字号参考750px的宽度 span class token
  • 在Nidia Xavier上使用docker遇到的问题

    在Nidia Xavier上使用docker遇到的问题 1 Xavier没有wifi模块2 在docker run gpus all时出现docker Error response from daemon OCI runtime creat
  • 【解决Anaconda3安装问题】conda --version 不是内部命令、没有script文件

    问题发现 xff1a 当我按照网上的教程安装完的时候 xff0c 到conda version出现下面错误 于是我寻求百度的帮助 xff0c 发现是环境变量的问题 但是我有点疑惑 xff0c 我按照的时候选择自动配置环境变量的 xff0c
  • 自动化测试框架有哪几种?全网最全面的总结来了

    目录 前言 什么是测试自动化框架 自动化测试框架的类型 测试自动化框架的好处 流行测试自动化框架 Robot Framework WebdriverIO Citrus Cypress Selenium Cucumber Gauge Cari
  • haproxy 基本维护命令和监控统计命令

    1服务管理命令 使用rpm包安装 xff0c 服务器管理脚本安装在 etc rc d init d haproxy xff0c 用法如下 haproxy start stop restart reload condrestart statu
  • Docker:docker操作image及container

    操作容器container 列出所有容器 docker span class token function ps span a 删除单个容器 docker span class token function rm span caec5440
  • LinuxMint新手教程3:fcitx输入法的安装与配置

    大概新手人都曾纠结过LinuxMint下的输入法配置问题 其实这个问题也挺容易的 下面我就以安装ppa源中的sogou输入法为例来为大家讲解 xff1a 安装搜狗输入法大概用如下命令就能解决了 xff1a sudo add apt repo
  • ping 原理与ICMP协议及Ping命令的过程与返回信息分析

    一 ping 原理与ICMP协议 ping 的原理 ping 程序是用来探测主机到主机之间是否可通信 xff0c 如果不能ping到某台主机 xff0c 表明不能和这台主机建立连接 ping 使用的是ICMP协议 xff0c 它发送icmp
  • [C++11] 循环引用

    前言 虽然C 43 43 11中的智能指针 xff0c 一定程度上简化了C 43 43 当中的内存管理 xff1b 但是 xff0c shared ptr lt gt 的使用同时也引出了另一个问题 xff1a 循环引用 例子 让我们先来看一