Qt原始碼分析之QPointer

2021-09-08 07:58:15 字數 2020 閱讀 6432

qpointer是乙個指標封裝類,其作用類似於智慧型指標,但是它最大的特點應該是在指標的控制上,它希望乙個qt的指標(當然是從qobject派生的)可以同時被多個類擁有,這在

介面程式設計中當然是很常見的事情了,但是當這個指標被刪除時,我們不希望再找到那兩個介面類然後通知它們,相反我們希望這兩個介面類可以直接判斷qpointer中的isnull方法

很自然的知道原始指標已經不存在了

一段很短的**,這裡需要的注意的是qpointer指標的使用

template

class qpointer

inline qpointer(t *p) : o(p)

inline qpointer(const qpointer&p) : o(p.o)

inline ~qpointer()

inline qpointer&operator=(const qpointer&p)

inline qpointer&operator=(t* p)

inline bool isnull() const

inline t* operator->() const

inline t& operator*() const

inline operator t*() const };

qpointer只是乙個簡單的模板,對qmetaobject的相關操作做了簡單的封裝,這裡的基本思想是

在qpointer構造的時候呼叫qmetaobject::addguard(&o),把t的指標加入qmetaobject內的乙個雜湊表中,

在qpointer析構的時候呼叫qmetaobject::removeguard(&o),把t的指標從雜湊表中刪除

這是乙個qmetaobject中靜態成員,該雜湊表的定義如下:

typedef qmultihashguardhash;

這個雜湊表儲存的是指標的值和指標的位址,因此加入的**如下:

void qmetaobject::addguard(qobject **ptr)

qwritelocker locker(guardhashlock());

hash->insert(*ptr, ptr);

}為什麼不是只儲存乙個指標呢,原來是為了防止誤刪除,看看刪除的**:

void qmetaobject::removeguard(qobject **ptr) }

} 只有在it.value() == ptr的時候才會刪除

但是等等,當刪除普通指標時又如何更新這個雜湊表呢?

delete pbutton;如何通知qmetaobject中的雜湊表更新?

答案是在qobject中,請注意qobject的析構函式

qobject::~qobject()

d->wasdeleted = true;

d->blocksig = 0; // unblock signals so we always emit destroyed()

// set all qpointers for this object to zero

guardhash *hash = ::guardhash();

if (hash)

}emit destroyed(this);

qconnectionlist *list = ::connectionlist();

if (list)

if (d->pendtimer)

}d->eventfilters.clear();

// delete children objects

if (!d->children.isempty())

這裡做了很多很多的事情,其中的**

// set all qpointers for this object to zero

guardhash *hash = ::guardhash();

if (hash)

}就是更新qmetaobject中雜湊表的

這也就是單基類的好處,可以在這裡控制很多事情

QT 原始碼分析 1

編寫 qt 的時候,使用的語句是 include,對應的是qobject檔案,該檔案的位置可以在qt creator中用ctrl 滑鼠檢視,具體目錄為 5.10.1 mingw53 32 include qtcore,該檔案中只有一句話 include qobject.h qobject h的位置為...

原始碼分析之LayoutInflater

簡介 inflate填充的過程 viewstub,merge,include的載入過程 layoutinflater系統服務的註冊過程 systemserviceregistry類有個靜態 塊,完成了常用服務的註冊,如下 static 註冊am registerservice context.act...

原始碼分析之HashMap

首先hashmap繼承了abstractmap,並且實現了map cloneable和serializable三個介面。cloneable和serializable是比較常規的兩個介面,在這裡並不作為重點。重點將會放在abstractmap和map兩個規範上。其中abstractmap是乙個抽象類,...