Invalid use of incomplete type on qt private class

2019-06-01 17:09发布

问题:

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 :)

回答1:

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