先看看这三个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类进行管理。