参考:https://www.cnblogs.com/qicosmos/p/5090159.html
利用function和map构造一个简单工厂,生产的具体类需要继承自工厂生产的基类。利用模板类稍作改进,扩展到工厂方法。
工厂看上去是这样的
template
class Factory
{
public:
typedef std::string KEY;
template
using CONSTRUCT = std::function ;
template
using MAP_KEY_GENERATOR = std::map>;
protected:
static Factory & Get()
{
static Factory factory;
return factory;
}
static MAP_KEY_GENERATOR _mapFunc;
}
这里的键是创建对象时提供的唯一标识,可以是string,其实也可以是typeid(class)的哈希值等等。CONSTRUCT提供一个构造函数。Base指向工厂生产产品的基类。
原代码中提供的私有函数对象封装了默认和形参构造函数的注入,使用new是为了复用代码,返回智能指针构造的对象
template
struct Register_t
{
Register_t(const KEY& key)
{
Factory ::Get()._mapFunc.emplace(key, [] {return new Inherit(); });
}
template
Register_t(const KEY& key, Args...args)
{
Factory ::Get()._mapFunc.emplace(key, [=] {return new Inherit(args...); });
}
};
上述的形参构造中无法在创建对象时才进行赋值,增加一个成员函数提高扩展性
void Register(const KEY key,const Factory ::CONSTRUCT & constrct)
{
Factory ::Get()._mapFunc.emplace(key, constrct);
}
接下来是一组生产具体对象的接口
static Base* produce(const KEY& key)
{
if (_mapFunc.find(key) == _mapFunc.end())
{
return nullptr;
}
return _mapFunc[key]();
}
static SPTR produce_share(const KEY& key)
{
return SPTR (produce(key));
}
static UPTR produce_unique(const KEY& key)
{
return UPTR (produce(key));
}
借助c++11 提供的特性,不需要100行代码,一个高复用的工厂方法基本成形
使用起来像这样,定义一些基类和具体类
class IBase
{
public:
virtual ~IBase() {};
virtual void Foo() {};
private:
};
class IBase2
{
public:
virtual ~IBase2() {}
virtual void Foo2() {}
private:
};
class InheritClass:public IBase
{
public:
InheritClass()
{
std::cout << "build 1\n";
}
~InheritClass()
{
std::cout << "destory 1\n";
}
void Func1()
{
std::cout << "funcs\n";
}
void Foo()
{
std::cout << "fucking work\n";
}
private:
};
class InheritBClass :public IBase
{
public:
InheritBClass()
{
std::cout << "bulid2\n";
}
~InheritBClass()
{
std::cout << "destory2\n";
}
void Foo()
{
std::cout << "func2\n";
}
};
class InheritBase2 :public IBase2
{
public:
InheritBase2()
{
std::cout << "build 3\n";
}
InheritBase2(int a)
{
std::cout << "build 3 a:" << a << "\n";
}
InheritBase2(const std::string& b)
{
std::cout << "build 3 b:" << b << "\n";
}
~InheritBase2()
{
std::cout << "destory 3\n";
}
void Foo2()
{
std::cout << "base2:: foo2\n";
}
};
InheritBase2* Gene()
{
std::cout << "Gene!\n";
return new InheritBase2();
}
然后测试一波。需要先创建工厂类,再向工厂注册生产品,调用produce_进行生产。
void TestFactory()
{
Factory baseFactory;
Factory::Register_t reg("build");
Factory::Register_t reg2("build2");
auto pa = baseFactory.produce_share("build");
pa->Foo();
std::cout << "typed id " << typeid(InheritBClass).hash_code()<<"\n";
auto pb = baseFactory.produce_unique("build2");
std::cout << "typed id2 " << typeid(*pb).hash_code()<<"\n";
Factory base2Factory;
Factory::Register_t reg3("build3");
auto pc = base2Factory.produce("build3");
int a = 1;
std::string b = "23333";
Factory::Register_t reg4("build4", b);
auto pc2 = base2Factory.produce_share("build4");
auto func = [] {return new IBase2(); };
base2Factory.Register("test",std::bind(&Gene));
auto pd = base2Factory.produce("test");
}