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();