C++ 具有实例化模板的切换枚举的工厂

C++ 具有实例化模板的切换枚举的工厂,c++,templates,design-patterns,factory,c++03,C++,Templates,Design Patterns,Factory,C++03,我在代码库的不同位置有以下层次结构模式: enum DerivedType { A, B, C }; class Base { public: static Base* Create(DerivedType t); }; template <DerivedType T> class Derived : public Base { }; 问题是有许多这样的Base->Derived层次结构,基本上相同的Create()copy实现到处粘贴。这里有没有一种优雅而又易于理

我在代码库的不同位置有以下层次结构模式:

enum DerivedType {
    A, B, C };

class Base {
public:
  static Base* Create(DerivedType t);
};

template <DerivedType T>
class Derived : public Base {
};

问题是有许多这样的
Base->Derived
层次结构,基本上相同的
Create()
copy实现到处粘贴。这里有没有一种优雅而又易于理解的方法来避免重复?

您可以将其作为一个模板

template<typename Base, typename Derive, template<Derive> class Derived>
Base* Base::Create(Derive t) {
  switch (t) {
  case Derive::A: return new Derived<Derive::A>;
  case Derive::B: return new Derived<Derive::B>;
  case Derive::C: return new Derived<Derive::C>;
  default: return nullptr;
  }
}
模板
Base*Base::创建(派生t){
开关(t){
案例派生::A:返回新的派生;
案例派生::B:返回新的派生;
案例派生::C:返回新的派生;
默认值:返回空ptr;
}
}

<>但是假设只有<代码> <代码> >代码> b>代码>和<代码> c>代码> > <结构>枚举> < /> > < /p> ,而不是使用C++样式枚举,可以使用java样式枚举,其中每个值是从公共基础派生的类的单体。p> 然后在基类上定义一组纯虚函数,创建所需的派生类风格,并在每个单例中适当地实现它们

然后,您可以使用
t->createDerived()
,而不是
switch(t)…


或者更简洁地说:用多态性替换switch。

我们可以抽象出工厂细节,并依靠客户机为我们提供枚举到类类型的映射:

template<typename ENUM, typename T>
struct Factory
{
    typedef std::map<ENUM, T*(*)()> map_type;
    static map_type factoryMapping_;

    static T* Create(ENUM c)
    {
        return factoryMapping_[c]();
    }

    static void Init(map_type _mapping)
    {
        factoryMapping_ = _mapping;
    }
};

template<typename ENUM, typename T>
typename Factory<ENUM, T>::map_type Factory<ENUM,T>::factoryMapping_;
现在我可以定义枚举和关联的类层次结构:

enum ClassType {A, B};
struct Foo
{
    virtual void PrintName() const
    {
        std::cout << "Foo\n";
    }
};

typedef Factory<ClassType, Foo> FooFactory ;

struct DerivedOne : public Foo
{
    virtual void PrintName() const
    {
        std::cout << "DerivedOne\n";
    }
};

struct DerivedTwo : public Foo
{
    virtual void PrintName() const
    {
        std::cout << "DerivedTwo\n";
    }
};
enum类类型{A,B};
结构Foo
{
虚空PrintName()常量
{

std::cout谢谢。这与C++03兼容吗?对于
Create
,只有一个模板参数如何工作?谢谢。我仍然需要至少一个开关(t),因为我仍然使用普通的旧枚举作为输入。我想这很好。您想为两个基本->派生层次结构绘制一个实现吗?不太想,我完全相信您可以填写详细信息。
template<typename Base, typename Derived>
Base* CreateDerived()
{
    return new Derived();
}
enum ClassType {A, B};
struct Foo
{
    virtual void PrintName() const
    {
        std::cout << "Foo\n";
    }
};

typedef Factory<ClassType, Foo> FooFactory ;

struct DerivedOne : public Foo
{
    virtual void PrintName() const
    {
        std::cout << "DerivedOne\n";
    }
};

struct DerivedTwo : public Foo
{
    virtual void PrintName() const
    {
        std::cout << "DerivedTwo\n";
    }
};
// set up factory
std::map<ClassType, Foo*(*)()> mapping;
mapping[A] = &CreateDerived<Foo, DerivedOne>;
mapping[B] = &CreateDerived<Foo, DerivedTwo>;
FooFactory::Init(mapping);

// Use the factory
Foo* f = FooFactory::Create(A);
f->PrintName();