轉自:http://www.tuicool.com/articles/qmI7Bf安全
故事的背景是這樣的,咱們在寫QT程序的時候或者在開始寫QT程序以前總會看到這樣的語句app
QApplication app(argc, argv);
這是什麼呢? QApplication這個類是繼承QCoreApplication的,而QCoreApplication有繼承函數
QObject的,而QObject就是QT中最基本的基類,也就是QT的根基了,這裏就從QCoreApplicationui
提及吧,頭文件中有這樣的開始this
class Q_CORE_EXPORT QCoreApplication : public QObject
Q_CORE_EXPORT是什麼呢?若是在編寫動態庫時,定義DLL符號,Q_GUI_EXPORT就是導出函數或者類spa
了,若是在應用程序中使用時,不定義Dll符號,Q_GUI_EXPORT就是導入類或者函數了,這裏固然是導命令行
入了,咱們寫的但是命令行的,不是編寫動態庫,下面就是一些函數和變量的定義了,看到這裏我震指針
驚了code
QCoreApplication * instance ()
定義一個指向本身的實例,啊?這是要鬧哪樣啊?難道要調用本身不成,實現就在類內,由於是靜態的對象
static QCoreApplication *instance() { return self; }
就是返回一個 self
static QCoreApplication *self;
是一個私有的靜態成員變量,實如今類外
QCoreApplication *QCoreApplication::self = 0;
這下算是知道這個 self是作什麼的了,但是這裏有個疑問,連 QCoreApplication本身都沒被建立
呢,哪來的指向 QCoreApplication的指針存在呢?這裏我的的解釋是靜態成員的建立應該類建立之
前就已經存在了,至於這個指向暫且就不考慮了,或許系統會解決這個問題吧,這裏就當成是一個指
針吧。
這裏有必要看一下這個QCoreApplication類的構造函數
QCoreApplication::QCoreApplication(int &argc, char **argv) : QObject(*new QCoreApplicationPrivate(argc, argv)) { init(); QCoreApplicationPrivate::eventDispatcher->startingUp(); #if defined(Q_OS_SYMBIAN) && !defined(QT_NO_LIBRARY) // Refresh factoryloader, as text codecs are requested during lib path // resolving process and won't be therefore properly loaded. // Unknown if this is symbian specific issue. QFactoryLoader::refreshAll(); #endif #if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) d_func()->symbianInit(); #endif }
下面看着有點暈了,這裏就只看 init();這個函數,就在構造函數的下面,這裏的代碼更多了,
這裏只寫咱們關注的一行
void QCoreApplication::init() { QCoreApplication::self = this; }
這裏對 self進行了賦值,這就讓這個self指向了當前這個對象,而不是什麼也不指了,這個self就可
以代替當前對象來使用了,固然這隻能在類內,由於self是私有的,要在類外使用是否是應該定義一
個共有成員函數什麼的,先把疑問留在這裏。
說完這個靜態成員變量self仍是沒有解決這裏爲何要鬧這樣的問題,原來咱們在類定義的上一行看
到這樣的代碼
#define qApp QCoreApplication::instance()
定義了一個 qApp宏,這個宏也就成了一個指針,指向的是本身,這樣作又有什麼用呢
當咱們在主程序中定義了 QCoreApplication app(argc, argv);對象的時候徹底是不須要用qApp這
個宏的啊,可是若是出了主函數要用這個對象怎麼辦,傳嗎?這樣比較麻煩,QT用這個指向本身的東
東就是幫助咱們解決這樣要在主函數外使用app這個對象的而找不到對象的苦惱。好了,在函數外你就
用qApp吧,這樣會不會有什麼問題呢?這個東西在內存嗎?嘿嘿,這是靜態的啊,就在內存呆着呢,大
膽的去用這個指向本身的宏指針吧,只要app沒析構這東東就一直在內存。
下面來講明一下QApplication,這個是從 QCoreApplication繼承來的,
#define qApp (static_cast<QApplication *>(QCoreApplication::instance()))
在類定義前有一段這樣的代碼,這裏也是取 self這個指向本身的指針可是要作一個類型轉換,至於這個類型轉換是否安全,我想應該是安全的,由於至關因而從基類往派生類轉換,基類有的應該是對拷貝的,可是這裏的static會不會對這個形成困擾還不是很清楚,總之,要轉換後這個qApp才能在主函數外使用。
這裏還要說明的是這個 QCoreApplication是否是單例的問題,網上有不少人認爲是單例,也有不少人同意,可是我實踐了一下應該不是單例
for(int i = 0 ; i < 3 ; ++i) { QCoreApplication app; }
這裏這樣的操做時容許的,由於以前的已經析構了,QT中說的只容許建立一個是指在一個函數內,只能建立一個,這裏顯然不是,單例的實現通常都是經過私有構造函數來實現的,這裏的構造函數是共有的顯然不是單例的節奏。