Qt-QPointer的使用

       在使用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"。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小王哥编程

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

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

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

打赏作者

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

抵扣说明:

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

余额充值