[Interest] correct d_ptr implementation

Constantin Makshin cmakshin at gmail.com
Mon Nov 11 21:54:42 CET 2013


Yes, I meant the "private subclassing" in a way like the one used by Qt
where it's used to both hide internals from the outer world and reduce
memory overhead by sharing one 'd_ptr' field between many classes.

But no, 'd_ptr' must be private to prevent classes derived from
DisplayWidget from changing the pointer after the object has been
constructed (DisplayWidget may still need to have that ability for
copy/move operators or something like that), Q_DECLARE_PRIVATE and Q_D use
small inline wrapper methods to give access to the object 'd_ptr' points to
without giving [direct] access to the pointer itself.
On Nov 12, 2013 12:11 AM, <andre at familiesomers.nl> wrote:

> Ok, but if your 'private' class is designed to be derived from, then I
> guess it was not all that private after all. It is more like it is to be
> protected instead of private. If the class really is private (for
> instance by not using a displaywidget_p.h for declaring it, but by just
> forward-declaring it from the private section of DisplayWidgets
> declaration in displaywidget.h and keeping all the rest in
> displaywidget.cpp instead), then I fail to see the point of either.
> There is no need for a private constructor or assignment operator then,
> as nobody can access them anyway, right?
>
> If you want to allow subclassing the private part (like Qt does), then I
> guess you're right. But IMHO that means that the d_ptr isn't really
> private, but rather it has become protected instead.
>
> André
>
> Constantin Makshin schreef op 11.11.2013 19:42:
> > Right, but:
> > 1) classes derived from DisplayWidget may want to derive their *Private
> > counterparts from DisplayWidgetPrivate — in this case private section
> > will make DisplayWidgetPrivate's internals accessible only to this
> > class
> > itself and its friend DisplayWidget;
> > 2) since not all compilers support "= delete" from C++11, placing an
> > intentionally-unimplemented constructor[s] and/or assignment operator
> > into the private section is the most common way to mark them as
> > unavailable.
> >
> > On 11/11/2013 10:22 PM, andre at familiesomers.nl wrote:
> >> Constantin Makshin schreef op 11.11.2013 18:33:
> >>> 1) put your 'd_ptr' into a smart pointer of some kind (usually
> >>> QScopedPointer), your example leaks memory;
> >>> 2) placing 'q_ptr' in the public section doesn't make much sense
> >>> because
> >>> it's supposed to be used only by the DisplayWidgetPrivate instance to
> >>> access its "owner" (DisplayWidget doesn't need any external
> >>> information
> >>> to access itself :) );
> >>> 3) I guess the second "public" section in DisplayWidgetPrivate was
> >>> supposed to be "private" :) .
> >>>
> >>> Other than that, your example looks OK to me.
> >>>
> >> How much sense does it make to have a private section in the private
> >> DisplayWidgetPrivate class at all? Everything in there is private for
> >> DisplayWidgets use anyway, right?
> >>
> >> André
> >>
> >>
> >>> On 11/11/2013 06:40 PM, Graham Labdon wrote:
> >>>> Hi
> >>>> I am developing a library and in Qt Tradition I want to use the
> >>>> d_ptr
> >>>> pattern.
> >>>> I have no previous experience of using this pattern and have a
> >>>> simple
> >>>> example working but wanted to check that my implementation is
> >>>> correct.
> >>>> To that end I have set out my classes below and would be grateful if
> >>>> anyone could confirm that my approach is correct(or not)
> >>>>
> >>>> Thanks
> >>>>
> >>>> Header file
> >>>>
> >>>> #ifndef DISPLAYWIDGET_H
> >>>> #define DISPLAYWIDGET_H
> >>>> #include "DisplayWidgetsGlobal.h"
> >>>> #include <QWidget>
> >>>>
> >>>> class DisplayWidgetPrivate;
> >>>>
> >>>> class DISPLAYWIDGETS_EXPORT DisplayWidget : public QWidget
> >>>> {
> >>>>         Q_OBJECT
> >>>>
> >>>> public:
> >>>>         DisplayWidget(QWidget *parent);
> >>>>         ~DisplayWidget();
> >>>>
> >>>> private:
> >>>>         DisplayWidgetPrivate* d_ptr;
> >>>>         Q_DECLARE_PRIVATE(DisplayWidget)
> >>>> };
> >>>>
> >>>> #endif // DISPLAYWIDGET_H
> >>>>
> >>>>
> >>>> Private Header file
> >>>>
> >>>> #include "DisplayWidget.h"
> >>>>
> >>>> class QLabel;
> >>>> class DisplayWidgetPrivate
> >>>> {
> >>>> public:
> >>>>         DisplayWidgetPrivate (DisplayWidget* parent);
> >>>>         void init();
> >>>>
> >>>>         QLabel* m_label;
> >>>>         DisplayWidget* const q_ptr;
> >>>>         Q_DECLARE_PUBLIC(DisplayWidget)
> >>>>
> >>>> public:
> >>>>         DisplayWidgetPrivate();
> >>>> };
> >>>>
> >>>>
> >>>> Implementation file
> >>>>
> >>>> #include <QLabel>
> >>>> #include "DisplayWidget.h"
> >>>> #include "DisplayWidget_p.h"
> >>>>
> >>>> DisplayWidgetPrivate::DisplayWidgetPrivate(DisplayWidget* parent)
> >>>>         : q_ptr(parent)
> >>>> {
> >>>>
> >>>> }
> >>>>
> >>>> void DisplayWidgetPrivate::init()
> >>>> {
> >>>>         m_label = new QLabel("This is a label",q_ptr);
> >>>> }
> >>>>
> >>>> DisplayWidget::DisplayWidget(QWidget *parent)
> >>>>         : QWidget(parent),
> >>>>           d_ptr(new DisplayWidgetPrivate(this))
> >>>> {
> >>>>         Q_D(DisplayWidget);
> >>>>         d->init();
> >>>> }
> >>>>
> >>>> DisplayWidget::~DisplayWidget()
> >>>> {
> >>>>
> >>>> }
> >
> >
> > _______________________________________________
> > Interest mailing list
> > Interest at qt-project.org
> > http://lists.qt-project.org/mailman/listinfo/interest
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20131112/009591ec/attachment.html>


More information about the Interest mailing list