Qt 對象間的父子關系


C++中只要有一個new就必須要有一個delete與之對應

但是Qt中的對象之間有特殊的關系

 

 

Qt 對象間的父子關系

每一個對象都保存有它所有子對象的指針

每一個對象都有一個指向其父對象的指針

parent里面有個鏈表 鏈表的每一個元素都是就是指向子對象的 指針

  類似的每一個子對向都保存了一個指向父對象的指針

 

Qt中的對象如何指定其父對象?

成員函數:setparent;

 

 當調用setparent函數時,父對象將子對像加入到自己的鏈表中,子對像將一個指針指向父對象,這樣對象就產生了父子關系。

 

為證明上述新建一個控制台的應用程序

  

#include <QCoreApplication>
#include <QDebug>
void fcTest()
{
    QObject* p = new QObject();
    QObject* c1 = new QObject();
    QObject* c2 = new QObject();

    c1->setParent(p);//該函數執行后p執行那個的對象就變成了父類的對象
    c2->setParent(p);

    qDebug() << "c1: " << c1;//輸出c1對象的地址
    qDebug() << "c2: " << c2;

    const QObjectList& list = p->children();

    for(int i=0; i<list.length(); i++)//Qt中提供了想訪問數組的方式訪問這個鏈表
    {
        qDebug() << list[i];
    }

    qDebug() << "p: " << p;

    qDebug() << "c1 parent: " << c1->parent();//函數返回父對象的指針
    qDebug() << "c2 parent: " << c2->parent();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    fcTest();
    return a.exec();
}

 如果對代碼中的成員函數不理解可以到Qt的幫助文檔中直接找其說明

方法:1、搜索QObject類

        2、在該類的成員函數中找對應的函數了即可得到該函數的說明:Makes the object a child of parent.即指定一個對象的父類。

對於const QObjectList& list = p->children();同樣使用上面Qt中的文檔找到:

const QObjectList & QObject::​children() const

Returns a list of child objects. The QObjectList class is defined in the <QObject> header file as the following:

 typedef QList<QObject*> QObjectList;

可以知道該函數的返回值const QObjectList &類型的鏈表

其中QObjectList 又是一個 QList<QObject*>  即是一個鏈表,鏈表中的元素又是QObject對象類型指針

 

 

Qt對象銷毀時又會有那些事情?

當Qt對象被銷毀時,很有可能不止一個對象被銷毀,因為其銷毀時,會將該對象的子對象鏈表中的所有對象都銷毀。

 

 

 通過setparent就可以形成上面的對象數,當刪除obj3時,其子類obj4的對象也要會銷毀。

 

為證明上面的結論:

創建一個繼承QObject的類

 1 class MObj:public QObject
 2  {
 3 
 4     QString m_name;
 5  public:
 6      MObj(const QString& name)
 7     {
 8         m_name=name;
 9         qDebug()<<"Constructor:"<<m_name;
10       }
11 
12      ~MObj()
13      {
14      qDebug() << "Destructor: " << m_name;
15     }
16  };

測試函數:

 void delTest()
 {
     MObj* obj1=new MObj("obj1");
    MObj* obj2=new MObj("obj2");
     MObj* obj3=new MObj("obj3");
     MObj* obj4=new MObj("obj4");
    //構建對象數
     obj2->setParent(obj1);
     obj3->setParent(obj1);
     obj4->setParent(obj3);
 
     //刪除obj3
     delete obj3;
   
 //delete obj4;如果再次delete obj4就會出錯,
    //由於obj4已經被delete了,此時obj4是一個野指針,delete野指針肯定會內存出錯的
 }

 

完整代碼:

 1 #include <QCoreApplication>
 2 #include <QDebug>
 3 #include <QString>
 4 
 5 class MObj:public QObject
 6  {
 7     
 8     QString m_name;
 9  public:
10      MObj(const QString& name)
11     {
12         m_name=name;
13         qDebug()<<"Constructor:"<<m_name;
14       }
15      ~MObj()
16      {
17      qDebug() << "Destructor: " << m_name;
18     }
19  };
20 void delTest()
21 {
22     MObj* obj1=new MObj("obj1");
23     MObj* obj2=new MObj("obj2");
24     MObj* obj3=new MObj("obj3");
25     MObj* obj4=new MObj("obj4");
26     //構建對象數
27     obj2->setParent(obj1);
28     obj3->setParent(obj1);
29     obj4->setParent(obj3);
30     //刪除obj3
31     delete obj3;
32 }
33 int main(int argc, char *argv[])
34 {
35     QCoreApplication a(argc, argv);
36     delTest();
37     return a.exec();
38 }
View Code

 

結果:

可以看到析構函數被調用了兩次,包括obj4和obj3

 

小結:

 

 

 

 

 學習狄泰軟件Qt實驗教程學習筆記16課 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM