我按照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解决了模板化案例中的对象工厂注册问题。 但是,派生类的注册仍然是知道派生类可以实例化的类型的人的责任。 通常,类开发人员没有这样的知识 - 用户确实拥有它。 那么,是否有任何方法可以解雇用户免于注册派生类的责任?