У меня есть удобный шаблон фабрики объектов, который создает объекты по их именам идентификаторов типов. Реализация довольно очевидна: ObjectFactory
содержит карту от std::string
до функции создателя объекта. Затем все объекты, которые будут созданы, должны быть зарегистрированы на этом заводе.
Я использую следующий макрос для этого:
#define REGISTER_CLASS(className, interfaceName) \
class className; \
static RegisterClass<className, interfaceName> regInFactory##className; \
class className : public interfaceName
, где RegisterClass
-
template<class T, class I>
struct RegisterClass
{
RegisterClass()
{
ObjectFactory<I>::GetInstance().Register<T>();
}
};
Использование
class IFoo
{
public:
virtual Do() = 0;
virtual ~IFoo() {}
}
REGISTER_CLASS(Foo, IFoo)
{
virtual Do() { /* do something */ }
}
REGISTER_CLASS(Bar, IFoo)
{
virtual Do() { /* do something else */ }
}
Классы определяются и регистрируются на фабрике одновременно.
Проблема в том, что regInFactory...
статические объекты определены в файлах .h, поэтому они будут добавляться в каждую единицу перевода. Один и тот же создатель объекта будет зарегистрирован несколько раз, и, что более важно, будет много избыточных объектов со статической продолжительностью хранения.
Есть ли способ сделать такую элегантную регистрацию (не копировать / вставлять имена классов и интерфейсов), но не распространять избыточные статические объекты по всему миру?
Если для хорошего решения требуются определенные расширения VC ++ (не соответствующие стандарту C ++), я буду в порядке с этим.