C++/Qt 源码解读-预备篇

概述

编译Qt源码是为了更好的跟踪Qt内部实现,能跟进去却不一定能看懂,因为Qt源码有较多不很成文的约定或规则,如一堆堆得宏定义…

D指针

#define Q_D(Class) Class##Private * const d = d_func()
//##:把宏参数名与宏定义代码序列中的标识符连接在一起,形成一个新的标识符

粗了解过D指针的意义后,倒过来从头重新认识他!先来看看什么是动态库的二进制兼容,若动态库更新后,其调用者也必须(不改变代码)重新编译,可以说动态库(此次修改)是源代码兼容的。如果库的使用者需要修改自己的程序才能使用新库,则无任何等级的兼容性可言。动态库兼容性,只与该库的导出类/方法有关,与非导出无关。看看这篇亮点在评论的文章,新库(C/C++)头文件的变动不一定对调用者造成影响-若导出头文件无更改,则一定是兼容的,若有变化,则更可能不兼容,有可能兼容?大家讨论的都是C++动态库兼容问题,这是因为C库是自动符合ABI的吗?(暂时留下这两个疑问!!) D指针在Qt上的应用及实现 ,博文足够让读者对Q_D有个全面理解,我们重点来看看继承关系:

class Q_CORE_EXPORT QObject
{
	...
    Q_PROPERTY(QString objectName READ objectName WRITE setObjectName)
    Q_DECLARE_PRIVATE(QObject)
    ...
    protected:
    QObject(QObjectPrivate &dd, QObject *parent = 0);

protected:
    QScopedPointer<QObjectData> d_ptr; 
    ...
}

#define Q_DECLARE_PRIVATE(Class) \
    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr)); } \
    inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr)); } \
    friend class Class##Private;

Q指针

#define Q_Q(Class) Class * const q = q_func()

具体案例(QToolBox)
我们可以通过QToolBox的头文件,在qtoolbox.h中,通过Q_DECLARE_PRIVATE()等宏跳转到 qglobal.h 文件中,查看Q_Q Q_D的定义
Q_D(QToolBox);
QToolPrivate * const d = d_func();
然后后续代码就开始使用d->…

你可能感兴趣的:(C++/Qt)