设计问题 - 多重继承,C ++

时间:2012-11-29 14:06:50

标签: c++ visual-c++ inheritance multiple-inheritance

首先,我将介绍一些代码,然后对问题进行描述:

class CGUIObject
{
protected:
    int m_id;
    bool m_bVisible;

    // Other non-relevant fields and methods specific for gui object...
};

class CClickable
{
private:
    bool m_bClicked;
public:
    bool isClicked();
    void setClicked(bool bClicked);

    virtual bool wasClicked(const TPoint& clickPos) = 0;

    // Other non-relevant fields and methods specific for clickable object...
};

class CComponent : public CGUIObject
{
    // The only important part of this class is that it derives from CGUIObject
};    

class CButton : public CComponent, CClickable
{
    // The only important part of this class is that it derives from CComponent and CClickable
};

// Now there is a method in my EventManager which informs all clickables about left mouse click event
void CEventManager::lMouseButtonClickEvent(const CPoint& clickPos)
{
    // Go through all clickables
    for(unsigned int i = 0; i < m_clickableObjectsList.size(); i++)
    {
         TClickable* obj = m_clickableObjectsList[i];

         // Here I would like to also check if obj is visible
         if(obj->wasClicked(clickPos))
         {
          obj->setClicked(true);
          if(obj->m_pOnClickListener != nullptr)
               obj->m_pOnClickListener->onClick();
         return; // Only one object can be clicked at once
         }
    }
}

好的,你可以看到:

  • CButton派生于CComponent和CClickable
  • CComponent派生自CGUIObject
  • CGUIObject有m_bVisible字段对我很重要
  • 在EventManager中,我创建了一个CClickable *对象列表

现在我想通知已点击的特定CClickable对象,但只有它可见。我知道所有可点击的内容也来自CGUIObject(例如CButton),但它是一个CClickable *列表,因此可以理解我无法访问m_bVisible字段。我知道它只是表明我在设计上犯了一个错误,但有没有办法以优雅和简单的方式解决这个问题?

2 个答案:

答案 0 :(得分:2)

如果您知道所有可点击内容均来自CGUIObject,您可以使用dynamic_cast

CClickable* obj = m_clickableObjectsList[i];

// Here I would like to also check if obj is visible
if(obj->wasClicked(clickPos) && dynamic_cast<CGUIObject*>(obj)->m_bVisible)
{
  //...

如果clickable不是GUI对象,dynamic_cast在这种情况下会返回空指针,你应该在取消引用结果之前检查它。

答案 1 :(得分:1)

您必须在dynamic_cast中实施wasClicked,而不是使用CButton之类的内容来说明按钮是否不可见,而不是点击它。

bool CButton::wasClicked() {
    if(!m_bVisible) return false;
    /*previous logic*/
}