用模板类特化的方式实现工厂模式

Posted vxgaaagaa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用模板类特化的方式实现工厂模式相关的知识,希望对你有一定的参考价值。

关于工厂模式的相关概念,这里不赘述,以下给出一种使用模板类特化的方式实现示例:


/**
 * @file    factory.cpp
 * <pre>
 * Copyright (c) 2019, Gaaagaa All rights reserved.
 * 
 * 文件名称:factory.cpp
 * 创建日期:2019年02月17日
 * 文件标识:
 * 文件摘要:工厂模式的实现示例代码。
 * 编译命令:g++ -Wall -std=c++11 -o factory factory.cpp
 * 
 * 当前版本:1.0.0.0
 * 作    者:
 * 完成日期:2019年02月17日
 * 版本摘要:
 * 
 * 历史版本:
 * 原作者  :
 * 完成日期:
 * 版本摘要:
 * </pre>
 */

#include <map>
#include <iostream>

////////////////////////////////////////////////////////////////////////////////

class x_product_t
{
    // constructor/destructor
public:
    x_product_t(void) {  }
    virtual ~x_product_t(void) {  }

    // extensible interfaces
public:
    virtual int type(void) const = 0;
};

template< typename _Ty, int _Ptype >
class x_product_template_t : public x_product_t
{
    // common data types
public:
    typedef enum emConstValue
    {
        ECV_PRODUCT_TYPE  = _Ptype,  ///< x_product_t 的类型
    } emConstValue;

    using x_type_t  = _Ty;
    using x_super_t = x_product_template_t< _Ty, _Ptype >;

    // common invoking
public:
    static x_product_t * build(void)
    {
        return (new x_type_t());
    }

    // constructor/destructor
protected:
    x_product_template_t(void) {  }
    virtual ~x_product_template_t(void) {  }

    // overrides
public:
    virtual int type(void) const override
    {
        return _Ptype;
    }
};

//====================================================================

class x_factory_t
{
    // common data types
public:
    typedef x_product_t * (* x_func_build_t)(void);

    // constructor/destructor
public:
    x_factory_t(void)  {  }
    ~x_factory_t(void) {  }

    // public interfaces
public:
    bool register_ptype(int xtype, x_func_build_t xfunc_build)
    {
        std::map< int, x_func_build_t >::iterator itfind = m_map_func_build.find(xtype);
        if (itfind == m_map_func_build.end())
        {
            m_map_func_build.insert(std::make_pair(xtype, xfunc_build));
            return true;
        }

        return false;
    }

    void unregister_ptype(int xtype)
    {
        m_map_func_build.erase(xtype);
    }

    x_product_t * build(int xtype)
    {
        std::map< int, x_func_build_t >::iterator itfind = m_map_func_build.find(xtype);
        if (itfind != m_map_func_build.end())
        {
            return itfind->second();
        }

        return nullptr;
    }

    // data members
private:
    std::map< int, x_func_build_t >  m_map_func_build;
};

//====================================================================

typedef enum emProductType
{
    EPT_PRODUCT_A = 100,
    EPT_PRODUCT_B = 200,
    EPT_PRODUCT_C = 300,
} emProductType;

class x_product_A_t : public x_product_template_t< x_product_A_t, EPT_PRODUCT_A >
{
    friend x_super_t;

    // constructor/destructor
protected:
    x_product_A_t(void) { std::cout << "build : x_product_A_t" << std::endl; }
    virtual ~x_product_A_t(void) { std::cout << "destroy : x_product_A_t" << std::endl; }
};

class x_product_B_t : public x_product_template_t< x_product_B_t, EPT_PRODUCT_B >
{
    friend x_super_t;

    // constructor/destructor
protected:
    x_product_B_t(void) { std::cout << "build : x_product_B_t" << std::endl; }
    virtual ~x_product_B_t(void) { std::cout << "destroy : x_product_B_t" << std::endl; }
};

class x_product_C_t : public x_product_template_t< x_product_C_t, EPT_PRODUCT_C >
{
    friend x_super_t;

    // constructor/destructor
protected:
    x_product_C_t(void) { std::cout << "build : x_product_C_t" << std::endl; }
    virtual ~x_product_C_t(void) { std::cout << "destroy : x_product_C_t" << std::endl; }
};

//====================================================================

int main(int argc, char * argv[])
{
    x_factory_t xfactory;

    //======================================
    // 注册

#define REGISTER_PRODUCT(name)  xfactory.register_ptype(name::ECV_PRODUCT_TYPE, &name::build)

    REGISTER_PRODUCT(x_product_A_t);
    REGISTER_PRODUCT(x_product_B_t);
    REGISTER_PRODUCT(x_product_C_t);

#undef REGISTER_PRODUCT

    //======================================
    // 生产

    x_product_t * xpdt = nullptr;

    xpdt = xfactory.build(EPT_PRODUCT_A);
    std::cout << "xdpt type : " << xpdt->type() << std::endl;
    delete xpdt;

    xpdt = xfactory.build(EPT_PRODUCT_B);
    std::cout << "xdpt type : " << xpdt->type() << std::endl;
    delete xpdt;

    xpdt = xfactory.build(EPT_PRODUCT_C);
    std::cout << "xdpt type : " << xpdt->type() << std::endl;
    delete xpdt;

    //======================================

    return 0;
}

以上是关于用模板类特化的方式实现工厂模式的主要内容,如果未能解决你的问题,请参考以下文章

C++模板编程中只特化模板类的一个成员函数(花样特化一个成员函数)

4.工厂模式

C++ 工厂模式 类模板实现

C++ 工厂模式 类模板实现

模板的全特化与偏特化

仅针对一个索引的 C++ 方法模板特化