在院子裏看到一篇相關的文章寫得挺好,就把鏈接拷過來,何時用,何時看!html
http://www.cnblogs.com/hazir/p/new_and_delete.html程序員
還有在百度知道中,一個牛人的解答以下: app
當咱們使用父對象來建立一個對象的時候 ,父對象會把這個對象添加到本身的子對象列表中。當這個父對象被刪除的時候,它會遍歷它的子對象類表而且刪除每個子對象,而後子對象們本身再刪除它們本身的子對象,這樣遞歸調用直到全部對象都被刪除。 這種父子對象機制會在很大程度上簡化咱們的內存管理工做,減小內存泄露的風險。咱們須要顯試刪除(就是用DELETE刪除)的對象是那些使用NEW建立的而且沒有父對象的對象(切記是new的纔要delete,經過成員函數得到的對象,沒有特殊說明的,千萬不要隨便delete.)。若是咱們在刪除一個對象的父對象以前刪除它,QT會自動地從它的父對象的子對象列表中移除它的。 Qt 自動回收不像Java這種,有垃圾回收機制。 Qt 自動回收是靠父子關係。父親銷燬了。他的孩子也銷燬。 因此爲何 main函數 裏面main widget是分配在棧上的緣由。其餘new出來的東西都以這個widget做爲父親。 當程序最後結束了,main widget彈棧。。父親被銷燬。。孩子跟着被銷燬。。 因此若是你本身new 出來的。沒有父親,不刪除就會形成內存泄漏。函數
------------------------------ 轉載--------------------------------------------post
Qt中幫程序員作了一些內存回收的事情,但正由於這些反而讓對此不熟悉的人會屢屢犯錯。 收錄一篇不錯的文章:在C++中學習過程當中,咱們都知道:delete 和 new 必須 配對使用(一一對應):delete少了,則內存泄露,多了麻煩更大。Qt做爲C++的庫,顯然是不會違背C++的前述原則的。但是:在Qt中,咱們不少時候都瘋狂地用new,卻不多用delete,缺乏的 delete 去哪兒了?! 注:本文暫不涉及智能指針(smart pointer)相關的東西,你能夠考慮 Qt 智能指針學習 一文Qt半自動的內存管理在Qt中,如下狀況下你new出的對象你能夠不用親自去delete (但你應該清楚delete在何處被Qt調用的,怎麼被調用的): QObject及其派生類的對象,若是其parent非0,那麼其parent析構時會析構該對象(本文內容圍繞這一點展開) 除此以外,有些類的對象能夠接收設置一些特別的標記,好比:QWidget及其派生類的對象,能夠設置 Qt::WA_DeleteOnClose 標誌位(當close時會析構該對象)QAbstractAnimation派生類的對象,能夠設置 QAbstractAnimation::DeleteWhenStoppedQRunnable::setAutoDelete()MediaSource::setAutoDelete()...注意:這些用法會有些陷阱,請注意看本文最後的3個小例子。在Qt中,最基礎和核心的類是:QObject 。它的魔力很大,本文只關注兩點:父子關係deleteLater父子關係 在Qt中,每一個 QObject 內部都有一個list,用來保存全部的 children,還有一個指針,保存本身的parent。當它本身析構時,它會將本身從parent的列表中刪除,而且析構掉全部的children。注意:在 Qt 中,咱們常常會遇到 基類、派生類,或父類、子類。這是對於派生體系來講的,和在C++相關書中看到的徹底同樣,與這的parent無關父對象、子對象、父子關係。這是Qt中所特有的,也就是這兒的parent所引入的,與類的繼承關係無關創建與解除 Q_INVOKABLE QObject::QObject ( QObject * parent = 0 ) 建立一個QObject對象時,若是指定了父對象,它就會將本身添加到父對象的 children 列表中 QObject::~QObject () [virtual] 當一個QObject對象析構時,它會將本身從父對象的 children 列表中移除(parent非0的話) void QObject::setParent ( QObject * parent ) 經過該函數,將本身從原父對象的children中刪除,添加到新parent的children列表中注:這三個函數都是經過一個內部私有函數來實現的,這就是 QObjectPrivate::setParent_helper(QObject *o) 獲取父、子對象每一個QObject只有一個父對象: QObject * QObject::parent () const 子對象能夠有多個 const QObjectList & QObject::children () const 因此能夠根據條件來查找嘍: T QObject::findChild ( const QString & name = QString() ) const QList<T> QObject::findChildren ( const QString & name = QString() ) const deleteLaterdeleteLater 包含兩層意思了deletelater呵呵,彷佛這是廢話哈。刪除本身在去年春節前的時候吧,有人對 obj-> deleteLater() 會像下面同樣調用delete: delete obj; 感到不解。而後我寫了這樣一個C++例子: class A { public: A(){} void deleteMe() { delete this; } }; int main() { A * a = new A; a->deleteMe(); return 0; } 應該不須要解釋吧laterQt 是事件驅動的,因此發送一個刪除事件到事件系統就能夠啦: void QObject::deleteLater() { QCoreApplication::postEvent(this, new QEvent(QEvent::DeferredDelete)); } 事件循環稍後看到該事件就會將其派發會這個widget: bool QObject::event(QEvent *e) { switch (e->type()) { ... case QEvent::DeferredDelete: ... 一些例子無關痛癢?很簡短、很熟悉的一個例子是不?可是 若是你發現對象的析構函數始終不被成功調用,會有什麼感受? #include <QApplication> #include <QLabel> int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel *label = new QLabel("Hello Qt!"); label->show(); return app.exec(); } 這是C++ GUI Programming with Qt 4 一書的第一個例子。咱們注意到這兒的 label 既沒有指定parent,也沒有對其調用delete。因此,這兒會形成內存泄露。 書中解釋說,對於這種小例子,這點內存泄露不算什麼。不清楚官方這個例子的意圖是什麼,或許是一開始就讓你們用指針吧。三種改進方式分配對象到stack而不是heap中 QLabel label("Hello Qt!"); label.show(); 設置標誌位,這樣,當咱們點擊關閉按鈕時,close()函數將會調用deleteLater label->setAttribute(Qt::WA_DeleteOnClose); 動手調用delete(不就是少了一個麼,咱們補上還不行麼) int ret = app.exec(); delete label; return ret; 單獨列一個吧強化一下對前一個例子的瞭解 #include <QApplication> #include <QLabel> int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel label("Hello Qt!"); label.show(); label.setAttribute(Qt::WA_DeleteOnClose); return app.exec(); } 運行正常,退出時會崩潰,由於label被close時,將會 delete 這兒label對象,但label對象卻不是經過new分配到heap中的。 爲了使得用戶減小本身顯式使用delete,Qt將delete隱藏的比較深。這樣一來,不使用new爲對象分配空間時,反倒須要多多當心了。隱蔽很深?看個小例子:這個程序退出時會直接崩潰。學習