2

最初にいくつかのコードを提示し、次に問題の説明をします。

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フィールドにアクセスできないことは理解できます。デザインを間違えたことを示しているだけですが、この問題をエレガントで簡単な方法で解決する方法はありますか?

4

2 に答える 2

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)
{
  //...

クリック可能オブジェクトがGUIオブジェクトでないdynamic_cast場合、そのような場合はnullポインターが返されるため、結果を逆参照する前にこれを確認する必要があります。

于 2012-11-29T14:13:34.533 に答える
1

のようなものを使用するのではなく、ボタンが非表示の場合はクリックされなかったと言うためにindynamic_castを実装する必要があります。wasClickedCButton

bool CButton::wasClicked() {
    if(!m_bVisible) return false;
    /*previous logic*/
}
于 2012-11-29T14:30:51.847 に答える