從 Qt 的 delete 說開來

2021-07-10 08:18:39 字數 2347 閱讀 6234

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::deletewhenstopped

qrunnable::setautodelete()

mediasource::setautodelete()

… 注意:這些用法會有些陷阱 ,請注意看本文最後的3個小例子。

父子關係

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 qobject::findchildren ( const qstring & name = qstring() ) const

deletelater

deletelater 包含兩層意思了

delete

later

呵呵,似乎這是廢話哈。

刪除自己

在去年春節前的時候吧,有人對

obj-> deletelater()

會像下面一樣呼叫delete:

delete obj;

感到不解。然後我寫了這樣乙個c++例子:

class a

void deleteme() };

int main()

應該不需要解釋吧

later

qt 是事件驅動的,所以傳送乙個刪除事件到事件系統就可以啦:

所以,這兒會造成記憶體洩露。

書中解釋說,對於這種小例子,這點記憶體洩露不算什麼。不清楚官方這個例子的意圖是什麼,或許是一開始就讓大家用指標吧。

三種改進方式

為了使得使用者減少自己顯式使用delete,qt將delete隱藏的比較深。這樣一來,不使用new為物件分配空間時,反倒需要多多小心了。

隱蔽很深?

看個小例子:這個程式退出時會直接崩潰 。

[喝小酒的網摘]

從 Qt 的 delete 說開來

在c 中學習過程中,我們都知道 qt作為c 的庫,顯然是不會違背c 的前述原則的。可是 注 本文暫不涉及智慧型指標 smart pointer 相關的東西,你可以考慮 qt 智慧型指標學習 一文 在qt中,以下情況下你new出的物件你可以不用親自去delete 但你應該清楚delete在何處被qt呼...

從 Qt 的 delete 說開來

delete qtclass clist 目錄 在c 中學習過程中,我們都知道 qt作為c 的庫,顯然是不會違背c 的前述原則的。可是 注 本文暫不涉及智慧型指標 smart pointer 相關的東西,你可以考慮 qt 智慧型指標學習 一文 在qt中,以下情況下你new出的物件你可以不用親自去de...

從 Qt 的 delete 說開來

原文 在c 中學習過程中,我們都知道 qt作為c 的庫,顯然是不會違背c 的前述原則的。可是 注 本文暫不涉及智慧型指標 smart pointer 相關的東西,你可以考慮 qt 智慧型指標學習 一文 在qt中,以下情況下你new出的物件你可以不用親自去delete 但你應該清楚delete在何處被...