转自:http://www.tuicool.com/articles/qmI7Bf

故事的背景是这样的,我们在写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中说的只允许创建一个是指在一个函数内,只能创建一个,这里显然不是,单例的实现一般都是通过私有构造函数来实现的,这里的构造函数是共有的显然不是单例的节奏。

[QT]QApplication和QCoreApplication的用法的更多相关文章

  1. Qt中两种定时器用法

    在Qt中使用定时器有两种方法,一种是使用QObiect类的定时器:一种是使用QTimer类.定时器的精确性依赖于操作系统和硬件,大多数平台支持20ms的精确度. 1.QObject类的定时器 QObj ...

  2. QT QApplication干了啥?

    ------------恢复内容开始------------ QCoreApplicationPrivate 会取得current thread; 在windows平台创建TLS变量,记录线程信息,并 ...

  3. Qt Sleep、QCoreApplication::processEvents()(最佳的平衡:一边发送消息,一边睡眠)

    sleep()//秒 msleep()//毫秒 usleep()//微秒 以前为了模拟鼠标点击用过这些函数,可以让进程中断,今天发现我原来的做法其实不对.这组函数会将你当前的线程/进程变为“睡眠”状态 ...

  4. Qt之QListView和QStandardItemModel用法

    note 个人理解, QListView 用于 显示数据,而数据的逻辑维护则由 QStandardItemModel 完成. QStandardItemModel 创建 if (nullptr == ...

  5. QT源码分析(从QApplication开始)

    QT源码分析 转载自:http://no001.blog.51cto.com/1142339/282130 今天,在给同学讲东西的时候,谈到了Qt源代码的问题,才发现自己对Qt机制的了解是在太少了,而 ...

  6. Qt程序继承QApplication发生崩溃的原因

    一.前情介绍 QApplication是Qt开发中经常用到的一个类,用来管理应用程序的生命周期.跟其相关的类还有QCoreApplication和QGuiApplication,分别用于不同场景下为应 ...

  7. qt 总结

    Qt中的每个类,都有一个对应的同名头文件,其中包含其类定义.例如要使用QApplication类,则需要在程序中添加" #include <QApplication>" ...

  8. Qt自定义事件的实现(转)

    原文:http://blog.csdn.net/michealtx/article/details/6866094 初学Qt,用了Qt自带的事件,然后想怎么才能定义自己的事件呢?又如何使用自定义事件呢 ...

  9. Qt之事件系统

    简述 在Qt中,事件就是对象,派生自QEvent抽象类,用来表示在应用程序中发生的事件,或是应用程序需要处理的外部活动产生的事件. Events可以被任何QObject派生的子类实例对象接收和处理,但 ...

随机推荐

  1. eclipse 安装Subversion1.82(SVN)插件

    Eclipse下SVN插件的安装,可以选择在线安装和离线安装两种方式: 2.(可选①)使用本地安装包安装插件 --填写插件名(可随意取名) --插件来源地址(①安装包,②使用网址) →Archie→选 ...

  2. DGbroker故障切换示例

    1.主库故障 SQL> startup ORACLE instance started. Total System Global Area bytes Fixed Size bytes Vari ...

  3. html lang="zh-cn"解决Mac版Firefox中文字体显示问题

    这两天在Mac下被Firefox的中文字体显示问题所困扰.在Firefox中将Sans-serif字体设置为SimSun-ExtB(新宋体)或英文字体(这时会用Mac默认中文字体),如下图: 浏览园子 ...

  4. 基于linux-2.6.35的class_create(),device_create解析

    基于linux-2.6.35的class_create(),device_create解析 作者:苗老师,华清远见嵌入式学院讲师. 从linux内核2.6的某个版本之后,devfs不复存在,udev成 ...

  5. 大话https演化过程(对称加密、非对称加密、公钥、私钥、数字签名、数字证书)

    大话https演化过程(包括概念:对称加密.非对称加密.公钥.私钥.数字签名.数字证书.https访问全过程)   在网络上发送数据是非常不安全的,非常容易被劫持或是被篡改,所以每次定向发送数据你都可 ...

  6. (4.20)sql server性能指标、性能计数器

    (4.20)sql server性能指标.性能计数器 常规计数器 收集操作系统服务器的服务器性能信息,包括Processor.磁盘.网络.内存 Processor 处理器 1.1 % Processo ...

  7. QQ-AR助人教版小学英语“动”起来

    日前,人教数字出版公司与腾讯QQ达成合作,将以小学英语3-6年级8本课本为合作试点,共同推出全国首个可AR识别的课本,在QQ-AR的帮助下,课本也能“动”起来,更加生动立体地展现在孩子眼前,让学习变得 ...

  8. MySQL和MSSQL差异(增量)备份的原理

    MySQL和MSSQL差异(增量)备份的原理 对于真正的增量备份来说,只需要记录当前每页最后的检查点的LSN,如果大于之前全备时的LSN,则备份该页面,否则不用备份 这大大加快了备份速度和恢复时间,同 ...

  9. 谈谈ConcurrentHashMap1.7和1.8的不同实现

    知止而后有定,定而后能静,静而后能安,安而后能虑,虑而后能得. ConcurrentHashMap 在多线程环境下,使用HashMap进行put操作时存在丢失数据的情况,为了避免这种bug的隐患,强烈 ...

  10. Mybatis入门和简单Demo

    一.Mybatis的诞生 回顾下传统的数据库开发,JDBC和Hibernate是使用最普遍的技术,但这两种ORM框架都存在一定的局限性: JDBC:最原生的技术,简单易学,执行速度快,效率高,适合大数 ...