C++11 的工厂方法

参考: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");
}

 

 

你可能感兴趣的:(C++11 的工厂方法)