简体   繁体   中英

Designing issue - multiple inheritance, C++

First I will present some code, then make a description of a problem:

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

Ok, so as you can see:

  • CButton derives both from CComponent and CClickable
  • CComponent derives from CGUIObject
  • CGUIObject has m_bVisible field which is important for me
  • In EventManager I have created a list of CClickable* objects

Now I'd like to inform specific CClickable object which was clicked but ONLY if it's visible. I know that all clickables also derive from CGUIObject (eg CButton), but it's a list of CClickable* so it's understandable I can't get access to m_bVisible field. I know it simply shows I've made a mistake in designing, but is there way to resolve this problem in some elegant and easy way?

If you know all clickables are derived from CGUIObject , you can use a 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)
{
  //...

If the clickable was not a GUI object, the dynamic_cast would return a null pointer in such case, and you should check this before dereferencing the result.

Rather than using something like a dynamic_cast , you have to implement the wasClicked in CButton to say if the button is invisible it was not clicked.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM