来自QObject的QT pimpl继承

来自QObject的QT pimpl继承,qt,inheritance,private,Qt,Inheritance,Private,在阅读Qt代码时,我有一个关于pimpl实现的基本问题。 以QWidget实现为例 QWidget ---inherits---> QObject | | contains contains | | \ / \ / QWidgetPrivate --

在阅读Qt代码时,我有一个关于pimpl实现的基本问题。 以QWidget实现为例

QWidget        ---inherits---> QObject
   |                              |
 contains                      contains
   |                              |
  \ /                            \ /
QWidgetPrivate ---inherits---> QObjectPrivate
现在QWidget有两个QObjectPrivate实例(通过继承和包含)。
为什么要这样实施?拥有同一对象的两个实例不是一种开销吗?

实例化
QWidget
时,没有两个
QObjectPrivate
实例。如果仔细查看
QObject
的头文件,您会发现一个受保护的构造函数:

protected:
    QObject(QObjectPrivate &dd, QObject *parent = 0);
QObject::QObject(QObjectPrivate &dd, QObject *parent)
    : d_ptr(&dd)
将QObjectPrivate实例设置为通过受保护构造函数传入的实例:

protected:
    QObject(QObjectPrivate &dd, QObject *parent = 0);
QObject::QObject(QObjectPrivate &dd, QObject *parent)
    : d_ptr(&dd)
这是所有不同的
QWidget
构造函数调用的构造函数。QWidget构造函数在
QWidgetPrivate
的instance中传递,正如您所注意到的,它是
QObjectPrivate
的子类。因此,QWidget中只存在一个QObjectPrivate实例

下面是默认的
QWidget
构造函数,说明了这一点:

QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
    : QObject(*new QWidgetPrivate, 0), QPaintDevice()
{
    QT_TRY {
        d_func()->init(parent, f);
    } QT_CATCH(...) {
        QWidgetExceptionCleaner::cleanup(this, d_func());
        QT_RETHROW;
    }
}