解析QPointer

在QT中,QPointer的出现必然有它的原因,肯定有很多我所不了解的优点,今天来study!
QPointer类是一个模板类,是为了QObject提供的一种监视指针。
先来看一下普通C++与QPointer指针声明方式有什么不同。

普通C++指针声明方式: T* p1;
QPointer指针声明方式:QPointer p2;

它们的最大不同就是:
当QPointer p2 指针引用的对象被销毁时候,p2指针会自动指向NULL,
而p1的引用对象如果被销毁,p1则不会自动指向NULL,而是会变成野指针。

解释一下就是当p1引用别的对象A,而这个对象A在别的地方可能一不小心被销毁了,而p1还在指向这块内存,p1的值是没有变的,可是p1指向的这块内存已经不是以前的对象A了,这时候再调用p1就相当于变成了野指针,操作的时候会引起不可预测的风险。这时候QPointer指针就会变得很有用,当p2指向的对象销毁了,p2会自动指向NULL,而不会变成野指针。

我们来看下一段代码

    QList <QWidget*> list1;
    QList <QWidget*> list2;
 
    QWidget *w1 = new QWidget;
    QWidget *w2 = new QWidget;
 
    list1.append(w1);
    list1.append(w2);
 
    list2.append(w1);
    list2.append(w2);
 
    foreach (QWidget *w, list1)
    {
        if(w)
        {
            list1.removeOne(w);
            delete w;
            w = NULL;
            qDebug() << "list1 is not null";
        }
        else
            qDebug() << "list1 is null";
    }
 
    foreach (QWidget *w, list2)
    {
        if(w)
        {
            qDebug() << "list2 is not null";
        }
        else
            qDebug() << "list2 is null";
    }

这时候我们来猜测一下结果,第一个foreach的时候,判断如果list1里的成员指向不为空,就删除此成员,并置为空,所以前三句应该都是“list1 is not null”;

重点来看第二个foreach,来判断list2中的成员指向是否为空,到此为止,list2中的值始终是没有变得,也就是它里面的指针不为空,所以打印出来的应该是"list2 is not null" 才对。结果是怎样的呢?

 list1 is not null
 list1 is not null
 
 list2 is not null
 list2 is not null

那么怎样避免这种情况呢,QPointer的作用就出现了。我们来变换一下刚才的代码:

QList <QPointer<QWidget>> list1;
QList <QPointer<QWidget>> list2;
 
QPointer<QWidget> w1 = new QWidget;
QPointer<QWidget> w2 = new QWidget;
 
 
list1.append(w1);
list1.append(w2);
 
list2.append(w1);
list2.append(w2);
 

允许结果是:

 list1 is not null
 list1 is not null
 
 list2 is null
 list2 is null
 

现在发现了,使用了QPointer之后,对于第一个foreach结果是没变化的,第二个foreach的时候,判断出来list2中的成员自动都指向了NULL,这就是QPointer的最大作用!

你可能感兴趣的:(界面编程,面向对象,qt,c++,开发语言)