QObject QObjectPrivate QObjectData

先看看这三个class的关系:

class QObject{
	inline QObjectPrivate* d_func(){return reinterpret_cast<QObjectPrivate*>(qGetPtrhelper(d_prt));}
	inline const QObjectPrivate* d_func() const{return reinterpret_cast<const QObjectPrivate*>(qGetPtrHelper(d_ptr));}
	friend class QObjectPrivate;
protected:
	QObject(QObjectPrivate& dd,QObject* parent=0);
protected:
	QObjectData* d_ptr;
}
QObject::QObject(QObjectPrivate& dd,QObject* parent)
	:d_ptr(&dd)
{
}


class QObjectPrivate:public QObjectData
{
	inline QObject* q_func(){return static_cast<QObject*>(q_ptr);}
	inline const QObject* q_func() const {return static_cast<const QObject*>(q_ptr);}
	friend class QObject;
}

QObjectData{
public:
	QObject* q_ptr;
	QObject* parent;
	...
	QMetaObject* metaObject;
}


从上面可以看出QObjectPrivate继承QObjectData

QObjectPrivate和QObject属于聚合关系,QObjectPrivate中保存着QObject的基本数据,只有QObject可以访问从而实现对数据的保护。QObject实现了大量的public方法。这两个类在内部可以互相访问:

QObject拥有QObjectData* d_ptr, 对d_ptr的初始化在其构造函数中

QObjectPrivate则拥有QObject* q_ptr,不过初始化q_ptr的却是QObject,在构造函数中d_ptr->q_ptr=this,QObject将自己的指针告诉了QObjectPrivate

QObject的作用体现在提供signal-slot机制的框架,

QObject::connect函数

const QMetaObject * smeta=sender->metaObject();
...
const QMetaObject* rmeta=receiver->metaObject();
...
QMetaObject::connect(sender,signal_index,receiver,method_index,type,types);

另外还提供了Q_OBJECT这个宏定义,有了它,QT可以使用MOC工具生成相应的moc_extendobject.cpp的文件,这个文件主要包括:

信号函数定义

void ExtendObject::Singal1(int t1)
{
	void* _a[]={0,const_cast<void*>(reinterpret_cast<const void*>(&_t1))};
	QMetaObject::activate(this,&staticMetaObject,0,_a);
}
槽函数的按名字调用能力(通过名字查找函数,并传入参数)

moc_extendobject.cpp

int ExtendObject::qt_metacall(QMetaObject::Call _c,int _id, void ** _a)
{
	_id=QThread::qt_metacall(_c,_id,_a);
	if(_id<0)
		return _id;
	if(_c==QMetaObject::InvokeMetaMethod)
	{
		switch(_id)
		{
			case0: Slot1((*reinterpret_cast<int(*)>(_a[1]))); break;
                	....
		}
	}
	return _id;
}
配套的还有2个数组:

static const uint qt_meta_data_ExtendObject[];
static const char qt_meta_stringdata_ExtendObject[];

然后使用staticMetaObject进行管理

const QMetaObject ExtendObject::staticMetaObject={
{&QThread::staticMetaObject,qt_meta_stringdata_ExtendObject,qt_meta_data_ExtendObject,0}
}


QObjectPrivate的作用则主要是封装了QObject实现过程需要的数据结构。例如关于线程亲和性的信息QThreadData* threaddata.

不过最终的信息实际上是关于对象之间的父子关系,所有直接继承或者间接继承了QObject的类的实例对象的父子信息都保存在QObjectPrivate中。父子关系的建立实在对象的构造函数中开始的:

QObject::QObject(QObject* parent)
{
	d->setParent_helper(parent);
}
void QObjectPrivate::setParent_helper(QObject* o)
{
	const int index=parent->children.indexof(q);
	if(parent->wasDeleted)
		parent->children[index]=0;
	else{
		parent->children.removeAt(index);
		...
	}
	parent->d_func()->children.append(q);
        //
}

研究上面的三个类是为了学习QTSDK中的代码编写风格,然后仿照。数据不再放在private下,而是使用private类进行管理。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值