程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> QApplication和QCoreApplication的用法

QApplication和QCoreApplication的用法

編輯:關於C語言

故事的背景是這樣的,我們在寫QT程序的時候或者在開始寫QT程序之前總會看到這樣的語句

QApplication app(argc, argv);

這是什麼呢?QApplication這個類是繼承QCoreApplication的,而QCoreApplication有繼承

QObject的,而QObject就是QT中最基本的基類,也就是QT的根基了,這裡就從QCoreApplication

說起吧,頭文件中有這樣的開始

class Q_CORE_EXPORT QCoreApplication : public QObject

Q_CORE_EXPORT是什麼呢?如果在編寫動態庫時,定義DLL符號,Q_GUI_EXPORT就是導出函數或者類

了,如果在應用程序中使用時,不定義Dll符號,Q_GUI_EXPORT就是導入類或者函數了,這裡當然是導

入了,我們寫的可是命令行的,不是編寫動態庫,下面就是一些函數和變量的定義了,看到這裡我震

驚了

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中說的只允許創建一個是指在一個函數內,只能創建一個,這裡顯然不是,單例的實現一般都是通過私有構造函數來實現的,這裡的構造函數是共有的顯然不是單例的節奏。

本文出自 “賣萌程序員” 博客,請務必保留此出處http://7677869.blog.51cto.com/7667869/1288735

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved