1

I want to use the d-pointer in a derived class with the help of Q_D macro.

Here is my parent class:

class DIGIKAM_EXPORT GraphicsDImgView : public QGraphicsView
{
    Q_OBJECT

public:
    class GraphicsDImgViewPrivate;

protected:
    GraphicsDImgViewPrivate* const d_ptr;

protected:
    Q_DECLARE_PRIVATE(GraphicsDImgView)
};

and my GraphicsDImgViewPrivate class:

class GraphicsDImgView::GraphicsDImgViewPrivate
{
public:

    GraphicsDImgViewPrivate()
    {
        scene            = 0;
        item             = 0;
        layout           = 0;
        cornerButton     = 0;
        panIconPopup     = 0;
        movingInProgress = false;
        showText         = true;
    }

    QGraphicsScene*           scene;
    GraphicsDImgItem*         item;
    SinglePhotoPreviewLayout* layout;

    QToolButton*              cornerButton;
    KPopupFrame*              panIconPopup;

    QPoint                    mousePressPos;
    QPoint                    panningScrollPos;
    bool                      movingInProgress;
    bool                      showText;
};

GraphicsDImgView::GraphicsDImgView(QWidget* const parent)
    : QGraphicsView(parent), d_ptr(new GraphicsDImgViewPrivate)
{
    Q_D(GraphicsDImgView);
    d->scene  = new QGraphicsScene(this);
    d->scene->setItemIndexMethod(QGraphicsScene::NoIndex);

    setScene(d->scene);
    d->layout = new SinglePhotoPreviewLayout(this);
    d->layout->setGraphicsView(this);
}

and in the derived class I write a method in which I want to use the d-pointer of GraphicsDImgView:

bool ImageRegionWidget::movingInProgress()
{
    Q_D(GraphicsDImgView);
    return d->movingInProgress;
}

However the build gives me the following error message

In member function ‘bool Digikam::ImageRegionWidget::movingInProgress()’:...path.... error: invalid use of incomplete type ‘class GraphicsDImgView::GraphicsDImgViewPrivate’

and

graphicsdimgview.h:128:11: error: forward declaration of ‘class GraphicsDImgView::GraphicsDImgViewPrivate’

I followed exactly the documentation so I don't know where I went wrong. Maybe I'm being careless. Please help me point out my error. Thanks :)

wceo
  • 934
  • 3
  • 18
  • 40

1 Answers1

3

I can't correct mistakes in your sample. Code is quiet dirty and unclear. I don't know article, where you get such recomendations. My proposal is to do pimpl in next way:

MyClass.h

class MyClassPrivate;
class MyClass
    : public QObject
{
Q_OBJECT
public:
  explicit MyClass(QObject *parent = 0);
~MyClass()
protected:
  MyClassPrivate * const d_ptr;
  MyClass(MyClassPrivate &dd, QObject * parent);
private:
  Q_DECLARE_PRIVATE(MyClass);
};

MyClass_p.h

#include "myclass.h"

class MyClassPrivate
{
  Q_DECLARE_PUBLIC(MyClass);
public:
  MyClassPrivate();
  virtual ~MyClassPrivate();

  MyClass * q_ptr;
};

MyClass.cpp

#include "myclass.h"
#include "myclass_p.h"

MyClassPrivate::MyClassPrivate()
{}

MyClassPrivate::~MyClassPrivate()
{}

MyClass::MyClass(QObject *parent)
  :QObject(parent)
  ,d_ptr(new MyClassPrivate())
{
  Q_D(MyClass);
  d->q_ptr = this;
}

MyClass::MyClass(MyClassPrivate &dd, QObject * parent)
  :QObject(parent)
  ,d_ptr(&dd)
{
  Q_D(MyClass);
  d->q_ptr = this;
}

MyClass::~MyClass()
{
  Q_D(MyClass);
  delete d;
}
Dmitry Sazonov
  • 8,801
  • 1
  • 35
  • 61
  • Thanks for your answer! I would like to know if the constructor `MyClass(MyClassPrivate &dd, QObject * parent)` is optional or not. Besides, I would like to know why in some methods where you used Q_D(MyClass) you used d->q_ptr? Thanks very much:) – wceo Aug 01 '13 at 13:47
  • q_ptr is used for access public class from private (with macros Q_Q, similar to Q_D). I used in once, for initialization. About protected constructors -i used this way for subclassing. For "thanks" there are special buttons like "vote up" and "accept" ;) – Dmitry Sazonov Aug 01 '13 at 14:21
  • I tried your code but for the moment still no luck... I think I must have messed up somewhere... – wceo Aug 01 '13 at 14:40
  • @wceo update your post with complete sample, that reproduce your problem. With all includes, splitted to files and so on. And show exact error message. – Dmitry Sazonov Aug 01 '13 at 14:45
  • Btw, try to replace `return d->movingInProgress;` with `return d->movingInProgress();` – Dmitry Sazonov Aug 01 '13 at 14:46