正確理解Widget::Widget(QWidget *parent) :QWidget(parent)這句話
最近很多學習Qt的小夥伴微信私信我,該如何理解下面段程式碼的第二行
1 Widget::Widget(QWidget *parent) : 2QWidget(parent) 3 { 4 }
為了統一回復大家,小豆君特意寫了這篇文章,方便初學者們學習。
在講解原因之前,先請大家看下面的一個例子:
#include <iostream> using namespace std; class Base { public: Base() :m_num(0){ cout << "this is Base()" << endl; } Base(int val):m_num(val){ cout << "this is Base(int val)" << endl; } private: int m_num; };
1 上方程式碼定義了一個基類Base,並且有兩個建構函式,一個是預設建構函式,一個是有一個整型引數的建構函式。
class BaseChild: public Base { public: BaseChild(){ cout << "this is BaseChild()" << endl; } BaseChild(int val): Base(val){ cout << "this is BaseChild(val)" << endl; } private: int m_num; };
2 上方程式碼定義了一個BaseChild類,並繼承Base類,同樣的,它也定義了兩個建構函式,一個預設,一個有整型引數。
int main(int argc, char *argv[]) { BaseChild child1; BaseChild child2(5); return 0; }
3 main函式例項化了兩個子類例項,child1,child2。
child1呼叫預設建構函式。child2呼叫有整型引數的建構函式。
現在,我們執行程式,會有如下列印:

image
看到了嗎,我們發現:
-
建立child1時,是先呼叫了Base的預設建構函式,再呼叫自己的預設建構函式。
-
建立child2時,是先呼叫了Base(int)這個建構函式,再呼叫自己的整型引數建構函式。
我們再回頭看BaseChild的建構函式
BaseChild(int val): Base(val){ cout << "this is BaseChild(val)" << endl; }
細心的同學,可能早就發現了,初始化列表中的Base(val)正是呼叫了我們Base基類的有參建構函式,而這樣的寫法就剛好是我們開頭程式碼中的那段:
Widget::Widget(QWidget *parent) :QWidget(parent)
所以Widget是呼叫了QWidget下面的建構函式
QWidget(QWidget* parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
所以得出如下總結:
總結:
1 如果不指定建構函式,則派生類會呼叫基類的預設建構函式
2 派生類建構函式的初始化列表只能初始化派生類成員,不能直接初始化繼承成員,如果想要呼叫基類的有參建構函式,則可以在派生類的初始化列表中顯示指定
以上總結,也告訴我們,當定義一個類時,最好為該類定義預設建構函式。
至此,我們明白了為什麼會有這樣的寫法。
好的,那麼我們又提出一個問題,“呼叫QWidget(parent)這個建構函式後,QWidget都做了哪些動作呢?”
下面是QWidget原始碼中的一部分節選:
QWidget::QWidget( QWidget *parent, const char *name, WFlags f ): QObject( parent, name ), QPaintDevice( PDT_WIDGET ), pal( parent ? parent->palette(): *qApp->palette() ){ if ( parent ) { QChildEvent *e = new QChildEvent( Event_ChildInserted, this ); QApplication::postEvent( parent, e ); } }
大家從上面可以看出,如果parent引數非空的話,那麼該建構函式使用了其父視窗的調色盤,並且傳送了QChildEvent事件,這會讓新的視窗成為parent所指視窗的子視窗,那麼當父視窗被刪除時,子視窗也會自動的被刪除。
這其實是用到了Qt物件樹的概念,關於物件樹,小豆君會在以後的分享中為大家介紹。
最後也希望大家多多支援小豆君的創作,關注小豆君的公眾號“小豆君Qt分享”,最新文章都會在公眾號第一時間釋出,或者你有不懂的問題,關注公眾號後,可加好友或進Qt群獲得答案。