隨著Symbian^3的推出以及可預見的Symbian^4的到來,加之Nokia在對於Meego應用平台的未來策越,越來越多的Symbian開發人員正在向著Qt過渡。
Symbian C++中引入了清除棧(CleanupStack)的概念,對於它的評判就不在這裡討論了,但對於用慣了Symbian C++的人來說,想要使用Qt的對象管理機制代替讓人頭疼的CleanupStack,還需要特別注意。
使用Qt,就不能不知道其中的對象管理機制。簡單的說,父(parent)對象擁有對其子(child)對象的管理權,而在這些管理權其中,最讓Qt使用者關注並樂道的,就是其對於記憶體的管理。但,一旦形成對象樹(object tree),就只用關注父物件的析構了嗎?
請看下面一段代碼:
#include <QtGui/QApplication>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel label(”http://www.google.com.hk“);
QWidget window;
hwLabel->setParent(&window);
window.show();
return a.exec();
}
這是一段典型的代碼,Qt使用者有時不會去注意QLabel到底是在棧上產生還是new出來在堆上產生。可能對於他們來說,因為擁有了對象管理,
所以他們也不必去關注子物件了。但真的是如此嗎?
請注意棧上對象的析構順序:
1.父物件window會先被析構掉,由於對象管理機制,其子物件label這時也將被window刪除
2.析構label,而此時的label已經被刪除,記憶體管理出現問題
對於使用Qt的對象管理機制,為避免這類問題的產生,需要轉變之前的代碼編寫形式:
1.盡量先建立父物件
2.子物件盡量在堆上產生
3.要清楚自己一手建立的對象樹組織,請相信,Qt編程中很多地方的處理邏輯都比這裡的複雜
4.當然,如果你想避重就輕,也可以所有對象都在堆上產生,只要程式邏輯正確,也可以避免這類問題。