2011-06-28 12 views
4

Qtコードを調べている間、私はpimplの実装についてこの基本的な質問をしました。 例としてQWidgetの実装を取ります。QObjectからのQT pimpl継承

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

今QWidgetには、QObjectPrivateのインスタンスが2つあります(継承および包含による)。 このように実装が行われたのはなぜですか?同じオブジェクトの2つのインスタンスを持つのはオーバーヘッドではありませんか?

答えて

4

QWidgetをインスタンス化するときには、QObjectPrivateのインスタンスは2つありません。

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

protectedコンストラクタ経由で渡されるQObjectPrivateのインスタンスを設定します:あなたはQObjectのヘッダファイルをよく見ると、あなたが保護されたコンストラクタわかります

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

をこれがありますコンストラクタは異なるコンストラクタのすべてによって呼び出されます。 QWidgetコンストラクタは、QWidgetPrivateのインスタンスに渡します。これは、指定したように、QObjectPrivateのサブクラスです。したがって、QWidgetにはQObjectPrivateのインスタンスが1つしか存在しません。

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; 
    } 
} 

はここでこれを示しデフォルトQWidgetコンストラクタです