成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳解 QT 父子與 QT 對象delete

移動開發
QWidget是所有在屏幕上顯示出來的界面對象的基類,它擴展了Qt對象的父子關系。一個Widget對象也就自然的成為其父Widget對象的子 Widget,并且顯示在它的父Widget的坐標系統中。

詳解 QT 父子與 QT 對象delete是本文要介紹的內容,講到了父對象子對象的關系,很詳細。不多說了,先來看內容。

很多C/C++初學者常犯的一個錯誤就是,使用malloc、new分配了一塊內存卻忘記釋放,導致內存泄漏。Qt對象模型提供了一種Qt對象之間的父子關系,當很多個對象都按一定次序建立起來這種父子關系的時候,就組織成了一顆樹。當delete一個父對象的時候,Qt對象模型機制保證了會自動的把 它的所有子對象,以及孫對象,等等,全部delete,從而保證不會有內存泄漏的情況發生。

任何事情都有正反兩面作用,這種機制看上去挺好,但是卻會對很多Qt的初學者造成困擾,我經常給別人回答的問題是:1,new了一個Qt對象之后,在什么 情況下應該delete它?2,Qt的析構函數是不是有bug?3,為什么正常delete一個Qt對象卻會產生segment fault?等等諸如此類的問題,這篇文章就是針對這個問題的詳細解釋。

在每一個Qt對象中,都有一個鏈表,這個鏈表保存有它所有子對象的指針。當創建一個新的Qt對象的時候,如果把另外一個Qt對象指定為這個對象的父對象, 那么父對象就會在它的子對象鏈表中加入這個子對象的指針。另外,對于任意一個Qt對象而言,在其生命周期的任何時候,都還可以通過setParent函數 重新設置它的父對象。當一個父對象在被delete的時候,它會自動的把它所有的子對象全部delete。當一個子對象在delete的時候,會把它自己 從它的父對象的子對象鏈表中刪除。

QWidget是所有在屏幕上顯示出來的界面對象的基類,它擴展了Qt對象的父子關系。一個Widget對象也就自然的成為其父Widget對象的子 Widget,并且顯示在它的父Widget的坐標系統中。例如,一個對話框(dialog)上的按鈕(button)應該是這個對話框的子 Widget。

關于Qt對象的new和delete,下面我們舉例說明。

例如,下面這一段代碼是正確的:

  1. int main()  
  2. {  
  3. QObject* objParent = new QObject(NULL);  
  4. QObject* objChild = new QObject(objParent);  
  5. QObject* objChild2 = new QObject(objParent);  
  6. delete objParent;  

我們用一張圖來描述這三個對象之間的關系:

詳解 QT 父子與 QT 對象delete

在上述代碼片段中,objParent是objChild的父對象,在objParent對象中有一個子對象鏈表,這個鏈表中保存它所有子對象的指針,在 這里,就是保存了objChild和objChild2的指針。在代碼的結束部分,就只有delete了一個對象objParent,在 objParent對象的析構函數會遍歷它的子對象鏈表,并且把它所有的子對象(objChild和objChild2)一一刪除。所以上面這段代碼是安 全的,不會造成內存泄漏。

如果我們把上面這段代碼改成這樣,也是正確的:

  1. int main()  
  2. {  
  3. QObject* objParent = new QObject(NULL);  
  4. QObject* objChild = new QObject(objParent);  
  5. QObject* objChild2 = new QObject(objParent);  
  6. delete objChild;  
  7. delete objParent;  

在這段代碼中,我們就只看一下和上一段代碼不一樣的地方,就是在delete objParent對象之前,先delete objChild對象。在delete objChild對象的時候,objChild對象會自動的把自己從objParent對象的子對象鏈表中刪除,也就是說,在objChild對象被 delete完成之后,objParent對象就只有一個子對象(objChild2)了。然后在delete objParent對象的時候,會自動把objChild2對象也delete。所以,這段代碼也是安全的。

Qt的這種設計對某些調試工具來說卻是不友好的,比如valgrind。比如上面這段代碼,valgrind工具在分析代碼的時候,就會認為objChild2對象沒有被正確的delete,從而會報告說,這段代碼存在內存泄漏。哈哈,我們知道,這個報告是不對的。

我們在看一看這一段代碼:

  1. int main()  
  2. {  
  3. QWidget window;  
  4. QPushButton quit("Exit", &window);  

在這段代碼中,我們創建了兩個widget對象,第一個是window,第二個是quit,他們都是Qt對象,因為QPushButton是從 QWidget派生出來的,而QWidget是從QObject派生出來的。這兩個對象之間的關系是,window對象是quit對象的父對象,由于他們 都會被分配在棧(stack)上面,那么quit對象是不是會被析構兩次呢?我們知道,在一個函數體內部聲明的變量,在這個函數退出的時候就會被析構,那 么在這段代碼中,window和quit兩個對象在函數退出的時候析構函數都會被調用。

那么,假設,如果是window的析構函數先被調用的話,它就會去 delete quit對象;然后quit的析構函數再次被調用,程序就出錯了。事實情況不是這樣的,C++標準規定,本地對象的析構函數的調用順序與他們的構造順序相 反。那么在這段代碼中,這就是quit對象的析構函數一定會比window對象的析構函數先被調用,所以,在window對象析構的時候,quit對象已 經不存在了,不會被析構兩次。

如果我們把代碼改成這個樣子,就會出錯了,對照前面的解釋,請你自己來分析一下吧。

  1. int main()  
  2. {  
  3. QPushButton quit("Exit");  
  4. QWidget window;  
  5. quit.setParent(&window);  

但是我們自己在寫程序的時候,也必須重點注意一項,千萬不要delete子對象兩次,就像前面這段代碼那樣,程序肯定就crash了。

最后,讓我們來結合Qt source code,來看看這parent/child關系是如何實現的。

在本專欄文章的第一部分“對象數據存儲”,我們說到過,所有Qt對象的私有數據成員的基類是QObjectData類,這個類的定義如下:

  1. typedef QList<QObject*> QObjectList;  
  2. class QObjectData  
  3. {  
  4. public:  
  5. QObject *parent;  
  6. QObjectList children;  
  7. // 忽略其它成員定義  
  8. }; 

我們可以看到,在這里定義了指向parent的指針,和保存子對象的列表。其實,把一個對象設置成另一個對象的父對象,無非就是在操作這兩個數據。把子對 象中的這個parent變量設置為指向其父對象;而在父對象的children列表中加入子對象的指針。當然,我這里說的非常簡單,在實際的代碼中復雜的 多,包含有很多條件判斷,有興趣的朋友可以自己去讀一下Qt的源代碼。

小結:QT 父子與 QT 對象delete的內容介紹完了,希望本文對你有所幫助。

責任編輯:zhaolei 來源: 互聯網
相關推薦

2011-06-24 09:39:05

2011-06-23 13:38:27

QT 元對象 信號

2011-07-04 15:48:57

Qt 桌面

2011-06-21 17:23:40

QT 編譯

2011-06-23 14:05:32

Qt 事件機制

2011-06-28 11:05:19

Qt QWidget Eventable

2011-09-07 16:57:31

QT WidgetQWidget

2011-06-20 17:33:58

Qt MeegoTouch Maemo

2011-06-28 15:01:01

Qt PIMPL

2011-06-20 15:13:08

Qt 對象模型

2011-07-01 12:52:50

Ubuntu Qt wxWidgets

2011-06-24 10:54:34

Qt Mysql

2011-06-17 10:19:11

Qt QWidge QSetting

2011-06-17 09:58:26

Qt Chapter QObject

2011-06-24 12:58:49

Qt LineEdit

2011-07-04 17:18:23

Qt SQLite 數據庫

2011-07-04 16:12:00

QT QWidget

2011-06-28 16:18:24

Qt QObject

2011-06-24 15:30:22

QT 皮膚 QSS

2011-06-20 11:14:09

Qt QxtGlobalS 熱鍵
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产一区二区激情视频 | 国产精品高潮呻吟久久av黑人 | 毛片免费在线 | 欧美久久精品一级c片 | 亚洲 欧美 另类 综合 偷拍 | 小早川怜子xxxxaⅴ在线 | 国产在线精品一区二区三区 | 91精品国产色综合久久 | 国产精品免费在线 | 免费一区在线观看 | 久久久久精 | 国产亚洲精品久久午夜玫瑰园 | 亚洲国产成人精品女人 | 青青草社区| 中文字幕在线不卡播放 | 中文字幕国产日韩 | 无码日韩精品一区二区免费 | 中文字幕亚洲欧美日韩在线不卡 | 国产一区二区三区在线 | 一区二区三区日 | 中文字幕在线视频精品 | 韩国理论电影在线 | 真人女人一级毛片免费播放 | 亚洲午夜视频在线观看 | 久久九九99 | 亚洲欧美视频一区 | 国产aaaaav久久久一区二区 | 热re99久久精品国99热观看 | av影音资源 | 日韩av啪啪网站大全免费观看 | 伊人精品久久久久77777 | 久久国产亚洲 | 黄免费观看视频 | 久久国产精品偷 | 国产成人免费视频网站视频社区 | 精品久久精品 | 在线免费观看日本 | 麻豆久久久久久久 | 国产精品久久 | 国产伦精品一区二区三区高清 | 久草网站 |