У меня есть несколько классов, которые имеют общий базовый класс, например:
class Base {};
class DerivedA : public Base {};
class DerivedB : public Base {};
class DerivedC : public Base {};
Теперь мне нужно знать, экземпляры каких из этих производных классов создавать во время выполнения (на основе ввода). Например, если ввод "DerivedA"
, мне нужно создать объект DerivedA
. Входные данные не обязательно являются строкой, это также может быть целое число - дело в том, что есть какой-то ключ, и мне нужно значение, соответствующее ключу.
Однако проблема в том, как мне создать экземпляр класса? C++ не имеет встроенного отражения, как C# или Java. Обычно предлагаемое решение, которое я нашел, - использовать фабричный метод следующим образом:
Base* create(const std::string& name) {
if(name == "DerivedA") return new DerivedA();
if(name == "DerivedB") return new DerivedB();
if(name == "DerivedC") return new DerivedC();
}
Этого было бы достаточно, если бы было всего несколько классов, но он стал бы громоздким и, вероятно, медленным, если бы были десятки или сотни производных классов. Я мог бы довольно легко автоматизировать процесс создания карты, чтобы создать std::map<std::string, ***>
, но я понятия не имею, что хранить в качестве значения. Насколько мне известно, указатели на конструкторы не допускаются. Опять же, если я создам фабрику, используя эту карту, мне все равно нужно будет написать фабричный метод для каждого типа, что сделает его еще более громоздким, чем в приведенном выше примере.
Что было бы эффективным способом решения этой проблемы, особенно при наличии большого количества производных классов?
factory pattern
- это часть решения - вам нужен какой-то (статический) метод/функция, которая может создать объект определенного класса. Вторая часть - это сопоставление имени с фабричным методом, которое можно легко реализовать с помощью карты, которая имеет имя в качестве ключа и указатель на фабричный метод в качестве значения. Третья часть — это механизм регистрации — каждый класс должен зарегистрировать свой фабричный метод на карте, используя уникальное имя (идентификатор типа). Я думаю, что OP уже знает это в целом, но ищет решение, когда есть много классов - person Andreas Fester   schedule 24.09.2014unordered_map<string, function<Base*(const string&)>>
. - person juanchopanza   schedule 24.09.2014