容器模式与专门的儿童

时间:2013-06-22 00:00:57

标签: c++ containers design-patterns

我有几个专业课。例如

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知道它有哪些孩子。但是我希望在容器上调用这些函数的便利性,所以我不必搜索子代,并找出在“转换”矩阵或向量时应该调用哪些函数。

我应该在这里使用什么样的正确模式?

基本上我想在根容器上设置一个矩阵或向量,让它传播给每个孩子而不是想要使用它。

想法?

1 个答案:

答案 0 :(得分:0)

基本composite pattern就足够了。要实现此功能,请在基类Transition中将成员函数声明为虚拟。这将允许您在Transition中维护Transition_Container个对象的列表,遍历列表并调用相应的成员函数。

#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。这与上面的建议非常相似,但删除了MatrixVectorTransition的依赖关系,并将处理不同类型的责任放在从它派生的类的实现上。如果有一些要求绝对阻止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);
        }
    }

};

我建议使用Boost或C ++ 11标准库中的shared_ptrunique_ptr来维护Transition对象的列表。

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

我没有在上面的例子中包含这个,因为我不知道你是否熟悉使用它。如果你不是我建议调查。