2014年4月16日 星期三

qt 自動刪除 child object

Memory management in Qt? 提到 qt 會 delete child objects。來看看是怎麼回事。

qt_src/src/corelib/kernel/qobject.h

 1 class Q_CORE_EXPORT QObject
 2 {
 3     Q_OBJECT
 4     Q_PROPERTY(QString objectName READ objectName WRITE setObjectName)
 5     Q_DECLARE_PRIVATE(QObject)
 6 
 7 public:
 8     Q_INVOKABLE explicit QObject(QObject *parent=0);
 9     virtual ~QObject();
10 }

QObject 的 dtor [virtual ~QObject();] 宣告為 virtual, 這就是 qt 可以自動呼叫 child objects dtor 的秘密。這通常在 QWidge 上, 只要 delete main widget, main widget 內的所有 child widget 都會正常的解構, 就不用寫一堆 delete 的程式碼。在某種程度上對於記憶體的管理幫了不少忙。

不需要看 source code, 寫個小程式測試一下就可以證明了。

commit c4ec6abf13142e89c8034ce9a2d9912bc2c6e5f1
https://github.com/descent/progs/tree/master/qt_thread1

測試了這樣的行為。

要符合兩個條件才能使這樣的功能正常運作:

1.
記得把繼承 QWidget 的 parent 傳給 QWidget (L14), 這應該沒問題, 繼承一個 class 通常都會這樣寫。

13 MyWidget::MyWidget ( QWidget * parent, Qt::WindowFlags f)
14   : QWidget(parent, f)
15 {
16 }

2.
18 Widget::Widget():m_label(new QLabel), m_button(new QPushButton("Button")), m_worker(new Worker)
19 {
20   new MyWidget(this);
21 }

要把 this 傳給這個繼承的 widget (L20), 如果傳 0, 無法自己呼叫 dtor, 需要自己手動 delete。

沒有留言:

張貼留言

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。