Qt-QPointer的使用

2023-10-30

       在使用Qt的时候,你是否遇到过这样的场景,从外部传来一个QObject的指针,当使用这个指针的时候,害怕它已经被释放了?如果我们在一个对象A中引用了另一个对象B,当对象B被析构的时候,A对象其实是不知道B已经被析构。这个时候再使用B的话就会导致崩溃。参考如下代码

class A : public QObject
{
    Q_OBJECT
public:
    A(): m_widget(nullptr) { }
    void setWidget(QWidget *w)
    {
        if (w == nullptr)
            return;
        m_widget = w;
    }

    void showWidget()
    {
        if (m_widget == nullptr)
            return;
        m_widget->show();
    }
private:
    QWidget *m_widget;
};

      如果m_widget在其他地方被释放掉了,再调用showWidget就是导致崩溃,因为m_widget == nullptr肯定是false。要解决这个问题有2种方式:

  1. 连接destroyed信号,把m_widget重新设置成nullptr。setWidget的代码如下:
    void setWidget(QWidget *w)                              
    {                                                       
        if (w == nullptr)                                   
            return;                                         
        m_widget = w;                                       
        connect(m_widget, &QWidget::destroyed, this, [this]{
            m_widget = nullptr;                             
        });                                                 
    }                                                       
  2. 使用QPointer,QPointer可以看作是一个智能指针类型。QPointer类是一个模板类,提供指向QObject的受保护指针。需要注意的是模板类型必须是QObject或QObject的派生类,并且QPointer对象在析构的时候不会去释放受保护的指针。因为重载了T *operator->() const,所以我们可像使用普通指针一样使用。修改之后的class A代码如下:
class A : public QObject
{
    Q_OBJECT
public:
    A(){ }
    void setWidget(QWidget *w)
    {
        m_widget = w;
    }

    void showWidget()
    {
        if (m_widget) {
            m_widget->show();
        } else {
              qDebug() << "The widget has been destroyed";
        }
    }
private:
    QPointer<QWidget> m_widget;
};

测试代码:

QWidget *w = new QWidget;
A *a = new A;

a->setWidget(w);
a->showWidget();

delete w;
a->showWidget();

        第一次调用showWidget的时候,由于w没有被释放,所以可以显示正常调用。当第二次调用showWidget的时候,w已经被释放了,所以会打印出"The widget has been destroyed"。

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

Qt-QPointer的使用 的相关文章

随机推荐

  • 为什么宏定义和函数定义运行结果不一样?

    函数定义 include
  • JUC-16. CAS

    想了解更多JUC的知识 JUC并发编程合集 1 CAS的概述 CAS的全称为Compare And Swap 比较并交换 它是一条CPU并发原语 比较工作内存值 预期值 和主物理内存的共享值是否相同 相同则执行规定操作 否则继续比较直到主内
  • Python中FIR滤波和小波包滤波对比(MNE脑电数据处理)

    小波变换有信号显微镜之称 在EEG分析中也有广泛的应用 印象中小波算法是来源于地球物理解释的 之前有介绍过小波的一些资料和实现 https blog csdn net zhoudapeng01 article details 1070259
  • srand((unsigned int)time(NULL))的理解(C语言)

    在c语言中 碰到这句函数 srand unsigned int time NULL 的理解 目录 1 srand与rand的关系 2 time函数的用法 3 取任意数 1 srand与rand的关系 在C中srand函数经常跟rand函数一
  • 经典/最新计算机视觉论文及代码推荐

    今日推荐几篇最新 经典计算机视觉方向的论文 涉及诸多方面 都是CVPR2022录用的文章 具体内容详见论文原文和代码链接 Convnet新活力 论文题目 A ConvNet for the 2020s 论文链接 https arxiv or
  • python中debug断点调试

    python Debug 断点调试 断点 break point 是指在代码中指定位置 当程序运行到此位置时变中断下来 并让开发者可查看此时各变量的值 因断点中断的程序并没有结束 可以选择继续执行 方法1 脚本中运行 在需要设置断点的地方
  • commonjs, es6 module什么是循环依赖?

    什么是循环依赖 循环依赖是指模块A依赖于模块B 同时模块B依赖于模块A 比如下面这个例子 foo js const bar require bar js console log value of bar bar module exports
  • 使用亚马逊云科技人工智能内容审核服务,打造安全的图像生成和扩散模型

    生成式人工智能技术发展日新月异 现在已经能够根据文本输入生成文本和图像 Stable Diffusion 是一种文本转图像模型 可让您创建栩栩如生的图像应用 您可以通过 Amazon SageMaker JumpStart 使用 Stabl
  • vue3介绍,Vue3的新特性

    vue3的优势 Vue 是目前国内开发最火的前端框架之一 react vue angular的下载趋势 Vue3性能更高 体积更小 Vue的compositionAPI 组合式API 可以 更好的代码复用 方便构建大型项目 对TS的支持比较
  • 通过DButils与连接池C3P0实现对对数据库的增删改查操作

    需要准备的有 C3P0配置文件
  • Excel匹配两列相同内容到同一行

    1 打开一个excel文件 找到需要自动对齐的两列数据 这里根据需要模拟了两列 2 用鼠标左键单击选中C1单元格 3 在C1单元格内输入公式 IF COUNTIF B 1 B 156 A1 0 A1 4 输入完公式后回车 再次选中C1单元格
  • k8s面试题大全(持续更新中)

    目录 前言 docker的工作原理是什么 讲一下 docker的组成包含哪几大部分 docker与传统虚拟机的区别什么 docker技术的三大核心概念是什么 centos镜像几个G 但是docker centos镜像才几百兆 这是为什么 讲
  • Bootstrap验证

    1 readonly验证需要 重新更新 var bootstrapValidator notice info input form data bootstrapValidator bootstrapValidator updateStatu
  • MySql安装版安装最新教程(附错误解决 )

    目录 1 安装版自定义安装 2 问题总结 1 安装版自定义安装 如果需要安装版安装 可参考另一篇博客 MySql压缩版安装最新教程 附错误解决 链接 MySql官网 滑到最下面 上面的是企业版下载 需要付费 我们下载开源的社区版 在这里我下
  • 编译出现 WARNING: ‘aclocal-1.15‘ is missing on your system.问题解决

    最近在中标麒麟下编译opus 1 2 1 make时出现了WARNING aclocal 1 15 is missing on your system 问题 发现是版本问题 于是重新安装了automake 下面是安装过程 1 下载安装包 h
  • PID恒温控制

    1 PID三个环节的作用 PID三个环节各自的主要作用和效应 比例环节 起主要控制作用 使控制量向目标值靠拢 但可能导致振荡 积分环节 消除稳态误差 但会增加超调量 微分环节 产生阻尼效果 抑制振荡和超调 但会降低响应速度 2 比例系数与积
  • @NotEmpty、@NotBlank、@NotNull 区别和使用

    首先需要说明下 本提到的 NotEmpty NotBlank NotNull 分别是 javax validation constraints NotEmpty javax validation constraints NotBlank j
  • Menu菜单,MenuBar菜单栏,MenuItem菜单项

    Menu菜单 MenuBar菜单栏 MenuItem菜单项 菜单栏 public class MenuDemo public static void main String args Frame f new Frame Menu菜单 Men
  • WEB攻防-通用漏洞&水平垂直越权&购买逻辑漏洞

    目录 水平垂直越权 水平越权 垂直越权 访问控制原理 漏洞判别 防护 购买逻辑漏洞 知识点 详细介绍 防护 案例演示 优惠券 案例演示 CMS 订单修改 水平垂直越权 水平越权 同级用户权限共享 当用户访问数据时未对用户和id值进行有效的查
  • Qt-QPointer的使用

    在使用Qt的时候 你是否遇到过这样的场景 从外部传来一个QObject的指针 当使用这个指针的时候 害怕它已经被释放了 如果我们在一个对象A中引用了另一个对象B 当对象B被析构的时候 A对象其实是不知道B已经被析构 这个时候再使用B的话就会