2013-06-22 90 views
2

我有幾個專門的類。例如容器模式與專門的兒童

class Transition_Matrix : public Transition 
{ 
    SetMatrix(Matrix* pStartMatrix); 
}; 

class Transition_Vector : public Transition 
{ 
    SetVector(Vector* pStartVector); 
} 

class Transition_Container : public Transition 
{ 

} 

我想在Animate_Container做呼叫SetVector()或SetMatrix(),而不聲明功能需要被設定對象的每種類型。例如,我不想申報Animate_Container如下...

class Transition_Container : public Transition 
{ 
    SetMatrix(Matrix* pStartMatrix);//loops through all children calling SetMatrix 
    SetVector(Vector* pStartVector);//loops through all children calling SetVector 
} 

我不想Animate_Container知道它有哪些兒童。但我希望在容器上調用這些函數的方便性,所以我不必通過孩子搜索並找出在「過渡」矩陣或向量時應調用哪些函數。

我應該在這裏使用什麼正確的模式?

基本上我想在根容器上設置一個矩陣或向量,並讓它傳播給每個可能想要使用它的孩子。

想法?

回答

0

這裏基本的composite pattern就足夠了。要實現此目標,請在基類Transition中聲明成員函數爲虛擬。這將允許您在Transition_Container中維護Transition對象的列表,遍歷列表並調用相應的成員函數。

#include <vector> 

class Transition 
{ 
public: 
    // default impementation that does nothing 
    virtual void SetMatrix(Matrix*) {} 
}; 

class Transition_Container : public Transition 
{ 
    std::vector<Transition*> transitions_; 

public: 
    virtual void SetMatrix(Matrix* pStartMatrix) 
    { 
     for(std::vector<Transition*>::iterator it = transitions_.begin(); 
      it != transitions_.end(); 
      ++it) 
     { 
      (*it)->SetMatrix(pStartMatrix); 
     } 
    } 
}; 

如果你不想Transition知道可以使用,你可以使用boost:anyboost:any_cast各種數據類型。這與上面的建議非常相似,但從Transition中刪除了對MatrixVector的依賴關係,並將處理不同類型的責任置於從其派生的類的實現上。我只推薦這樣做,如果有一些要求絕對阻止Transition瞭解MatrixVector類型。

#include <vector> 
#include <boost/any.hpp> 

class Transition 
{ 
public: 
    // default impementation that does nothing 
    virtual void SetValue(boost::any&) {} 
}; 


class Transition_Matrix : public Transition 
{ 
    virtual void SetValue(boost::any& value) 
    { 
     try 
     { 
      Matrix *matrix = boost::any_cast<Matrix*>(value); 

      // do stuff 
     } 
     catch(const boost::bad_any_cast &) 
     { 
      return; 
     } 
    } 
}; 


class Transition_Container : public Transition 
{ 
    std::vector<Transition*> transitions_; 

public: 
    template<Arg> 
    void SetValueT(Arg* arg) 
    { 
     boost::any value = arg; 
     SetValue(value); 
    } 

    virtual void SetValue(boost::any& value) 
    { 
     for(std::vector<Transition*>::iterator it = transitions_.begin(); 
      it != transitions_.end(); 
      ++it) 
     { 
      (*it)->SetValue(value); 
     } 
    } 

}; 

我建議使用shared_ptr或升壓unique_ptr或C++ 11標準庫維護Transition對象,像這樣的列表。

std::vector<std::shared_ptr<Transition>> transitions_; 

我並沒有包括這在上面的例子,因爲我不知道,如果你熟悉使用這個呢。如果你不是,我建議看看它。

+0

是的,這是一個很好的答案,這是我以前實施它的方式。但是,我想知道是否有辦法做到這一點,以便Transition類不需要了解Matrix或Vector。 –

+0

_你爲什麼不想'過渡'知道'矩陣'和'矢量'? –

+0

@DannyDiaz我已經更新了我的答案,包括一個使用'boost :: any'的例子 –