gpt4 book ai didi

c++ - 带有切换实例化模板的枚举的工厂

转载 作者:太空狗 更新时间:2023-10-29 21:15:30 26 4
gpt4 key购买 nike

我在代码库的各个地方都有以下层次结构模式:

enum DerivedType {
A, B, C };

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

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

Create方法返回类 Derived<A> 的新对象, Derived<B> , 或 Derived<C> ,取决于它的论点:

Base* Base::Create(DerivedType t) {
switch (t) {
case A: return new Derived<A>;
case B: return new Derived<B>;
case C: return new Derived<C>;
default: return NULL;
}
}

问题是有很多这样的Base -> Derived层次结构,与 Create() 的实现基本相同到处复制粘贴。是否有一种优雅但易于理解的方法来避免此处重复?

最佳答案

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

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_;

现在客户的工作是为我们提供创建 Base* 给定一些枚举值的方法。

如果您愿意并且能够使用模板抽象派生类的创建,那么您可以节省大量的输入。

我的意思是,让我们创建一个模板函数来创建一个派生类(没有任何真正的正确性检查):

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

Live Demo

当然,这会稍微简化您的问题,即将工厂详细信息移出基类并暂时忽略子级本身已被模板化的情况。取决于在您的域中为每种类型创建良好的 CreateDerived 函数的难度,您最终可能不会节省大量的输入。

编辑:我们可以利用std::map::find 修改我们的Create 函数以返回NULL。 .为了简洁起见,我省略了它。如果您关心性能,那么是的,O(log n) 搜索渐近地比简单的切换慢,但我强烈怀疑这最终会成为热路径。

关于c++ - 带有切换实例化模板的枚举的工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37576790/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com