QtCoreApplication

QtCoreApplication

今天,继续研究关于QtCoreApplication的构造函数问题。

QCoreApplication::self = this;

该类保存了自身的指针,是静态方法,同时是私有成员,刚开始的时候以为是单例模式,后来发现好像也不是。

不过跟之前的断言放在一起,就发现了其真正的意图。

Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object");

该断言保证了QCoreApplication对象只能被创建一次,同时又采用了静态方法的方式将对象提供出来。现在知道了,原来这是一个变形的单例设计模式。

#ifndef QT_NO_THREAD

QThread::initialize();

#endif

这里的定义可以看出来,在控制台应用程序中,可以选择采用多线程方式,或者单线程方式。但是具体的线程实现,以后再做研究。

// use the event dispatcher created by the app programmer (if any)

if (!QCoreApplicationPrivate::eventDispatcher)

QCoreApplicationPrivate::eventDispatcher = d->threadData->eventDispatcher;

// otherwise we create one

if (!QCoreApplicationPrivate::eventDispatcher)

d->createEventDispatcher();

Q_ASSERT(QCoreApplicationPrivate::eventDispatcher != 0);

if (!QCoreApplicationPrivate::eventDispatcher->parent())

QCoreApplicationPrivate::eventDispatcher->moveToThread(d->threadData->thread);

d->threadData->eventDispatcher = QCoreApplicationPrivate::eventDispatcher;

这里通过应用程序创建并使用事件调度程序。如果线程中存在了调度程序对象,则赋值指针,否则得花,创建事件调度程序。

这里如果创建失败,程序会终止。

看来,我们需要对QThrad进行一步的研究了,否则无法解释接下来的问题了。

我们查看下QThreadinitialize方法。

if (qt_global_mutexpool)

return;

qt_global_mutexpool = QMutexPool::instance();

#if defined (Q_OS_WIN)

qt_create_tls();

#endif

这里可以看到,首先程序判定互斥池是否创建,如果全局的互斥池指针已经创建,则说明线程已经进行过初始化,直接返回。否则得花,进行对QmutexPool类进行实例化。现在发现,原来好多类的设计都采用了单例模式。

QMutexPoolinstance方法中,返回了全局的互斥池,这里应该是为了保证线程安全用的。调用的函数是:globalMutexPool(),但是该函数是以宏定义的形式进行实现的,比较隐蔽。

#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) /

Q_GLOBAL_STATIC_INIT(TYPE, NAME); /

static TYPE *NAME() /

{ /

if (!this_##NAME.pointer && !this_##NAME.destroyed) { /

TYPE *x = new TYPE ARGS; /

if (!this_##NAME.pointer.testAndSetOrdered(0, x)) /

delete x; /

else /

static QGlobalStaticDeleter<TYPE > cleanup(this_##NAME); /

} /

return this_##NAME.pointer; /

}

 

#define Q_GLOBAL_STATIC_INIT(TYPE, NAME) /

static QGlobalStatic<TYPE > this_##NAME = { Q_BASIC_ATOMIC_INITIALIZER(0), false }

发现宏Q_BASIC_ATOMIC_INITIALIZER没有找到,只能理解为一个原子整形数据,具体的实现就不清楚了,我们将宏替换掉,看是一个什么样的效果呢?

Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (true))

替换为

static QGlobalStatic< QMutexPool > this_globalMutexPool = { Q_BASIC_ATOMIC_INITIALIZER(0), false }

 

static QMutexPool * globalMutexPool () /

{ /

if (!this_ globalMutexPool.pointer && !this_ globalMutexPool.destroyed) { /

QMutexPool *x = new QMutexPool ARGS; /

if (!this_globalMutexPool.pointer.testAndSetOrdered(0, x)) /

delete x; /

else /

static QGlobalStaticDeleter< QMutexPool > cleanup(this_ QMutexPool); /

} /

return this_ globalMutexPool.pointer; /

}

这就是替换后的globalMutexPool()函数的实现,该函数的主要功能就是返回一个线程安全的函数全局互斥池对象的指针。

接下来我们可以看下事件调度者的实现问题。在Windows系统下,进行了如下定义:

#elif defined(Q_OS_WIN)

eventDispatcher = new QEventDispatcherWin32(q);

这里创建了Win32下的事件调度者对象,看样子,是一个很庞大内容了,今天就到这里还有其他事情要做,明天去看关于事件调度类的具体细节。

 

20091014日星期三 2333

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值