Как создать объекты, чей конструктор требует параметров из строки, содержащей имя класса? - PullRequest
0 голосов
/ 07 октября 2011

Есть ли способ создания объектов из строки, содержащей их имя класса?

У меня проблема в основном та же, что и с вопросом выше. Но мне нужно создать экземпляр класса с некоторыми параметрами. различное имя конструктора класса может потребовать различного количества переменных, и тип каждой переменной может также отличаться. И потому что класс содержит константные переменные, поэтому вы не можете создать его с новым T (), а затем установить для параметра правильное значение. карта "имя класса" - "конструктор", кажется, не подходит для моих нужд.

Есть ли альтернативы?

Ответы [ 2 ]

1 голос
/ 07 октября 2011

Я собираюсь предвосхитить это, сказав, что, возможно, C ++ не является подходящим языком для всего, что вы пытаетесь достичь. Чем больше вы пытаетесь контролировать свою программу с помощью внешних данных, тем ближе вы подходите к сценариям. И есть много более мощных вариантов, когда это ваша цель.

При этом, конечно, это возможно, хотя и не так легко. Два способа сразу приходят на ум. Первый - требовать, чтобы все применимые типы имели конструктор, который принимает std::string. Этот конструктор будет отвечать за собственный синтаксический анализ.

template<typename T> Base * createInstance(const std::string& s) { return new T(s); }
typedef std::map<std::string, Base*(*)(const std::string&)> map_type;
//...and similar changes as needed

Если вы не хотите изменять определения типов или это неприемлемо в противном случае [возможно, у ваших типов уже есть такой конструктор?], Избавьтесь от шаблона createInstance и предоставьте индивидуальные версии для каждого типа, который вы используете. интересует. Эта функция выполняет разбор и вызывает соответствующий конструктор.

map["derivedA"] = createDerivedA;
map["derivedB"] = createDerivedB;

Третий вариант может быть возможен при использовании вариадических шаблонов [или вариабельных шаблонов в стиле boost-esque], которые вернут вас к первоначальной простоте.

template<typename T, typename... Args>
Base* create(std::string) {
  //somehow pass the string to a generic function that packs the arguments into a tuple
  //then somehow unpack that tuple and pass the bits to the constructor
}

map["derivedA"] = create<derivedA, int, double, std::string>;

Однако я понятия не имею, как это осуществить, и даже если это возможно.

0 голосов
/ 07 октября 2011

Вы можете использовать паттерн фабричного дизайна.передайте вашу строку классу фабрики, а затем позвольте ей декодировать вашу строку, выбирая правильную версию конструктора и класса для вызова.Затем он передаст экземпляр правильного класса для использования оставшимся кодом.Вот некоторая информация шаблон фабричного дизайна

...