В C ++ нет отражения, поэтому вам следует переформулировать свой вопрос, пытаясь объяснить, какие требования вы бы выполнили с помощью отражающей его части.
В зависимости от ваших реальных ограничений и требований, существуетЕсть несколько вещей, которые вы можете сделать.Первый подход, который я выбрал бы, - это создание абстрактной фабрики, где конкретные фабрики могут регистрироваться и предоставлять простой интерфейс:
class Base {}; // shared base by all created objects
class ConcreteFactoryBase {
public:
virtual ~ConcreteFactoryBase() {}
virtual Base* create() const = 0; // actual construction
virtual std::string id() const = 0; // id of the types returned
};
class AbstractFactory
{
typedef std::map<std::string, ConcreteFactory* > factory_map_t;
public:
void registerFactory( ConcreteFactoryBase* factory ) {
factories[ factory->id() ] = factory;
}
Base* create( std::string const & id ) const {
factory_map_t::const_iterator it = factories.find( id );
if ( it == factories.end() ) {
return 0; // or throw, or whatever makes sense in your case
}
return (*it)->create();
}
~AbstractFactory(); // ensure that the concrete factories are deleted
private:
std::map<ConcreteFactoryBase*> factories;
};
Реальные бетонные фабрики могут быть реализованы вручную, но, вероятно, они могут быть шаблонизированы, есликонструкторы для разных типов требуют разных аргументов:
template <typename T>
class ConcreteFactory : public ConcreteFactoryBase {
public:
ConcreteFactory( std::string const & id ) : myid(id) {}
virtual Base* create() const {
return new T;
}
virtual std::string id() const {
return myid;
}
private:
std::string myid;
};
class Test : public Base {};
int main() {
AbstracFactory factory;
factory.register_factory( new ConcreteFactory<Test>("Test") );
}
При желании вы можете адаптировать подписи, чтобы вы могли передавать аргументы конструктору через разные слои.
Опять же, знаяфактические ограничения, некоторые другие подходы могут быть лучше.Подход clone()
, предложенный в другом месте, хорош (либо путем клонирования, либо путем создания пустого объекта того же типа).Это в основном смешивает фабрику с самими объектами, так что каждый объект является фабрикой объектов одного типа.Мне не очень нравится смешивать эти две обязанности, но это может быть один из самых простых подходов с меньшим количеством кода для написания.