Private implementation

From QtCentreWiki

Jump to:navigation, search


Private Implementation (aka. "pimpl") is a C++ programming idiom which can be used to reduce compilation times, to enhance encapsulation and to retain binary compatibility.

Pimpl built in Qt

Anyone who has ever peeked under the covers and looked into the sources of Qt has most likely noticed macros called Q_D and Q_Q. Along with Q_DECLARE_PRIVATE and Q_DECLARE_PUBLIC, these macros provide Qt's own pimpl mechanism.

QObject, the heart of the Qt object model, has a pointer to the private implementation in it's interface. The private implementation pointer, "d_ptr" cannot be set to anything custom as it would prevent QObject from reaching it's private implementation which it strictly relies on.

Each and every private implementation class in Qt inherits QObjectPrivate. For example QWidget has QWidgetPrivate and QPushButton has QPushButtonPrivate. Where some of these private implementations are declared in separate headers, others are not. This makes it, in most cases, impossible to use aforementioned macros in one's own projects.

For example, let's say I'm subclassing QPushButton. I would have to subclass the private implementation from QPushButtonPrivate to avoid destroying QPushButton's private implementation. But QPushButtonPrivate is declared in qpushbutton.cpp so it's basically impossible to subclass.

In addition to this, Qt's private headers/implementations are a subject to change. As it says in all the private headers:

//  W A R N I N G
//  -------------
// This file is not part of the Qt API.  It exists purely as an
// implementation detail.  This header file may change from version to
// version without notice, or even be removed.
// We mean it.

In conclusion, the pimpl built in Qt is of no use for one's own projects. It's not meant to be used and in many cases it's even impossible.

How to build your own pimpl mechanism

The Internet is full of various pimpl examples. To put it in a nutshell, you simply provide a pointer to the private implementation in the private interface of a class. Instead of storing private members directly to the class, place them into the private implementation class.

One can save himself or herself from building redundant mechanism from scratch to several classes by following the example of the pimpl technique used in Qt. This can slightly reduce the amount of handwork while declaring private implementation classes and later when referencing them. The following example makes use of the pimpl macros defined in Qt with only some minor modifications.

Further reading

jpn 23:24, 22 November 2006 (CET)