У меня есть удобный шаблон фабрики объектов, который создает объекты по именам идентификаторов их типов. Реализация довольно очевидна: 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++), я соглашусь с этим.