来自QObject的QT pimpl继承

时间:2011-06-28 22:02:26

标签: qt inheritance private

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

QWidget        ---inherits---> QObject
   |                              |
 contains                      contains
   |                              |
  \ /                            \ /
QWidgetPrivate ---inherits---> QObjectPrivate

现在QWidget有两个QObjectPrivate实例(通过继承和通过包含)。 为什么以这种方式完成实施?拥有同一个对象的两个实例不是一个开销吗?

1 个答案:

答案 0 :(得分:4)

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

protected:
    QObject(QObjectPrivate &dd, QObject *parent = 0);

将QObjectPrivate的实例设置为通过受保护的构造函数传递的实例:

QObject::QObject(QObjectPrivate &dd, QObject *parent)
    : d_ptr(&dd)

这是所有不同QWidget构造函数调用的构造函数。 QWidget构造函数传递QWidgetPrivate的实例,正如您所指出的那样,它是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;
    }
}