2011-06-28 33 views
4

在经历Qt代码时,我对pimpl的实现有了这个基本问题。 以QWidget实现为例。来自QObject的QT pimpl继承

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

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

回答

4

实例化QWidget时不存在两个QObjectPrivate实例。如果你在为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; 
    } 
}