与Qt的Pimpl成语

时间:2016-06-17 09:36:02

标签: c++ qt pimpl-idiom

我正在尝试使用Qt 5.6.0构建一个共享库,我想使用Pimpl。

我有一个要导出的类,这个类继承自QGraphicsScene,它本身继承自QObject:

// CustomScene.h
#include "customscene_global.h" // recommended header from Qt
#include <QGraphicsScene> // do not compile if not present 

// forward declarations
class CustomSceneImpl;
template <typename T> class QList;
class QString;
template <class Key, class T> class QMap;
// some other classes ...

class CustomScene : public QGraphicsScene
{
  Q_OBJECT

  public :
  // some public functions

  signals:
  // some custom signals

  public slots:
  // some custom public slots

  private:
    CustomSceneImpl *m_pimpl; // pointer to private members

};

如果我在此标题中#include <QGraphicsScene>,那么一切都很好,但我更愿意转发声明QGraphicsScene。但是,如果我这样做,我会得到以下编译错误:

error: invalid use of incomplete type 'struct QGraphicsScene'

我想我在使用QObject宏做错了,这是无法识别的,并且通常使用moc。

我知道有专门的Qt宏使用Pimpl(Q_D,..)但我真的不明白如何使用它们以及是否能解决这个问题。

感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

  

如果我在此标题中#include QGraphicsScene,那么一切都很好,但我更愿意转发声明QGraphicsScene。

QGraphicsScene继承:

,你无法做到这一点
class CustomScene : public QGraphicsScene

顺便说一句。这个错误与你实现PIMPL惯用法的方式无关(实际上看起来很好),不完整类型的继承根本不可能,因为编译器需要知道基类的大小/布局。

答案 1 :(得分:2)

由于前向声明的类没有关于内容的信息,因此您无法将其用于继承。

答案 2 :(得分:2)

您可以将PIMPL惯用法用于合成,而不是用于继承。如果您需要继承$(function(){ $(".removeClass").click(function () { var var1=$(this).data('employee'); $('#employee_'+var1).removeClass('popup-box-on'); }); }); ,则无法转发声明它。你必须包括它的完整定义。