2012-11-29 146 views
2

首先,我將介紹一些代碼,然後做出一個問題的描述:設計問題 - 多重繼承,C++

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字段。我知道這只是表明我在設計上犯了一個錯誤,但是有沒有辦法通過一些優雅和簡單的方式來解決這個問題?

+0

由於線性複雜性,我希望您的應用程序中的可點擊對象數量相當少。 –

+1

@MatthieuM。對不起,在這種情況下,「線性複雜性」是什麼意思? –

+0

您一次遍歷所有可點擊的對象,以檢查它們是否可見(並且事件應該分派給它們),或者它們不是(並且沒有必要完成)。因此,這至少需要與「Clickable」對象的數量成比例,即使只有少數人真正關心。 –

回答

1

與其使用諸如dynamic_cast之類的東西,您必須在CButton中實現wasClicked來說明該按鈕是否不可見,是否未點擊。

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

謝謝,這似乎是一個更好的主意 –

2

如果您知道所有clickables從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) 
{ 
    //... 

如果點擊的不是一個GUI對象時,dynamic_cast將返回在這種情況下,一個空指針,並你應該在解引用結果之前檢查它。

+0

用於檢查。 –

+0

謝謝你的回答,Angew。 :-) –