对象工厂注册模板类层次结构

时间:2018-05-02 13:16:43

标签: c++11 templates design-patterns factory

我按照Andrei Alexandrescu的书 Modern C ++ Design 的指导实现了一般的对象工厂,所以我可以像这样定义一个类层次结构(我将编写最简化的代码)方式,避免实现细节或内存分配/释放问题;我知道这些事情,我想集中讨论主要问题):

// File "base.h"
#include <string>
#include "singleton.h"
#include "object_factory.h"
class Base;

using SingletonBaseFactory = Singleton
<
     ObjectFactory
     <
         Base,         // Abstract product type
         std::string,  // Identifier type
         Base* (*)()   // Concrete product creator type
     >
>;

class Base {
    // Define the interface (virtual functions, virtual dtor)
public:
    // Wrap the Factory method
    static Base* Factory(const std::string& ID) {
        return SingletonBaseFactory::Instance().Factory(ID);
    }
};

// File "derived_1.h"
#include "base.h"
class Derived_1 : public Base { /* ... */ };

// File "derived_2.h"
#include "base.h"
class Derived_2 : public Base { /* ... */ };

并在相应的实现文件中的匿名命名空间中注册每个派生类:

// File "derived_1.cpp"
#include "derived_1.h"
namespace {
    Base* CreateDerived_1() {
        return new Derived_1;
    }

    const bool registered = SingletonBaseFactory::Instance().Register("Derived_1", CreateDerived_1);
}

// Same for Derived_2 in file "derived_2.cpp"

因此,想要在代码中使用此层次结构的用户只需使用正确的标识符调用Base::Factory方法:

// File main.cpp
#include"base.h"
int main(){
    Base* pb = Base::Factory("Derived_1");

    // Do stuff with pb

    return 0;
}

现在,假设我有一个模板类层次结构,比如说:

// File "baset.h"
#include <string>
#include "singleton.h"
#include "object_factory.h"

template<class T>
class BaseT;

template<class T>
using SingletonBaseTFactory = Singleton
<
    ObjectFactory
    <
        BaseT<T>,         // Abstract product type
        std::string,      // Identifier type
        BaseT<T>* (*)()   // Concrete product creator type
    >
>;

template<class T>
class BaseT {
    /*Define the interface*/ 
public:
    BaseT Factory(const std::string& ID) {
        return SingletonBaseTFactory<T>::Instance().Factory(ID);
    }
};

// File "derivedt_1.h"
#include "baset.h"
template<class T>
class DerivedT_1 : public BaseT<T> { /* ... */ };

在这种情况下,在使用类层次结构之前,注册是他想要使用的每种类型T的用户责任:

// File main.cpp
#include "baset.h"
#include "derivedt_1.h"

bool register_derived_1_int = SingletonBaseTFactory<int>::Instance().Register("Derived_1", [](){ return new DerivedT_1<int>; });

int main() {
    BaseT<int>* pb = BaseT<int>::Factory("Derived_1");
    return 0;
}

请记住每个派生模板类的ID对于每个类型T都是相同的,将注册职责委托给每个派生类(而不是用户)的开发人员是否有意义,即使在模板化的案例? 如果是这样,是否有解决方法来实现它?

修改

我发现这项工作https://www.artima.com/cppsource/subscription_problem.html解决了模板化案例中的对象工厂注册问题。 但是,派生类的注册仍然是知道派生类可以实例化的类型的人的责任。 通常,类开发人员没有这样的知识 - 用户确实拥有它。 那么,是否有任何方法可以解雇用户免于注册派生类的责任?

0 个答案:

没有答案