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課