C ++:实现多重继承的最佳实践

时间:2016-02-23 11:35:35

标签: c++ qt templates multiple-inheritance virtual-inheritance

我必须将两种类型的图形项(QGraphicsRectItemQGraphicsEllipseItem)的倍数添加到QGraphicsScene(添加到QGraphicsView)。每个图形项都应该能够与鼠标和键盘事件进行交互。所以最初我设计的课程如下。

初步设计:

class myQGraphicsRectItem : public QGraphicsRectItem
{
public:
    explicit myQGraphicsRectItem();
private:
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void keyPressEvent(QKeyEvent *event);
    void focusOutEvent(QFocusEvent *event);
    //Many events goes here
    void fnCreateRect();
};

class myQGraphicsRectItem : public QGraphicsEllipseItem
{
public:
    explicit myQGraphicsRectItem();
private:
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void keyPressEvent(QKeyEvent *event);
    void focusOutEvent(QFocusEvent *event);
    //Many events goes here
   void fnCreateCircle();
};

要知道如何避免重复的事件声明和定义,我会阅读以下答案:

最后将课程设计如下。

修改后的设计:

头文件

template <class T>
class myQGraphicsRectItem : public QGraphicsRectItem , public QGraphicsEllipseItem{
     /*commented the below event methods in the base classes*/
     void mousePressEvent(QGraphicsSceneMouseEvent *event);
     void keyPressEvent(QKeyEvent *event);
     void focusOutEvent(QFocusEvent *event);
     //Many events goes here
}

实施文件

template <class T> myGraphicsItem<T>::myGraphicsItem()
{
    this->T::setFlags(QGraphicsItem::ItemIsMovable|QGraphicsItem::ItemIsFocusable);
    this->T::setFocus();
}     

//**All event function definition goes here....**     

template <class T> QGraphicsItem *myGraphicsItem<T>::fnGetRectObject()
{
    fnCreateRect();
    return (T*)this;
}

调用代码

#include "mygraphicsitem.h"
#include "mygraphicsitem.cpp"

void MainWindow::on_PushButton_clicked()
{
    myGraphicsItem<myQGraphicsRectItem> *rr = new myGraphicsItem<myQGraphicsRectItem>();
    scene->addItem(rr->fnGetRectObject());
}

应用程序正在按预期使用此修改后的设计。但我对这种设计有一些疑问,如下:

  1. 这是处理这种情况的最佳做法还是应该使用初始方法?还是有任何其他最佳方法(编写单个代码来处理事件)?
  2. QGraphicsRectItemQGraphicsEllipseItem都继承自QAbstractGraphicsShapeItem。那么我需要处理虚拟基类概念吗?

2 个答案:

答案 0 :(得分:5)

哇,那是在考虑问题的解决方案!

  

还有其他最好的方法(编写单个代码来处理事件)?

对我来说,问题并不清楚你想要实现的目标,可能是由于尝试的解决方案,所以我将假设这两个类QGraphicsRectItem和{{1}你正试图用一个代码块来处理自定义事件,比如鼠标,键等。

在这种情况下,Qt会在调用installSceneEventFilter时为您提供所需的一切。

只需创建一个派生自QGraphicsEllipseItem的类,然后重新实现您想要处理的事件。然后使用QGraphicsItem

将此新类添加到其他实例
installSceneEventFilter

实例化过滤器并将其添加到其他类

class QGraphicsItemEventsFilter : public QGraphicsItem
{
    private:
        void mousePressEvent(QGraphicsSceneMouseEvent *event);
        void keyPressEvent(QKeyEvent *event);
        void focusOutEvent(QFocusEvent *event);
};

现在,QGraphicsItemEventsFilter* pFilter = new QGraphicsItemEventsFilter; QGraphicsRectItem* pRect = new QGraphicsRectItem; pRect->installSceneEventFilter(pFilter); QGraphicsEllipseItem* pEllipse = new QGraphicsEllipseItem; pEllipse->installSceneEventFilter(pFilter); pRect的所有事件都将由事件过滤器pFilter处理。

答案 1 :(得分:2)

我从Qt的经验中得出的一般答案(没有详细阅读您的代码)是:如果您认为必须使用多重继承来处理Qt类和子类,那么您很可能做错了 - 这反过来又是很可能是一个你完全不了解机制的迹象。 Qt设计得很好,如果你按照预期做事,你就不需要多重继承。

再试一次,然后去寻找你想要实现的目标。