2013-06-22 87 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'的例子 –