фон:Создать экземпляр класса на основе ввода строки
В моем игровом движке у меня есть общий «сценарий парсер», который используется для создания игровых объектов путем анализа файла сценарий. Таким образом, в коде у вас есть что-то вроде MyEntity* entity = MyScriptParer::Parse("filename.scr");
Любой класс, который должен быть доступен для скриптинга, наследуется от базового базового класса. Внутренне в игровом движке есть некоторые конкретные классы, которые используют это - частицы, шрифты и т.д., и все это прекрасно работает в синтаксический анализатор - см экстракт ниже
std::string line;
std::getline(ifs, line);
if (line == "[FONT]") {
CFont* f = new CFont();
f->readObject(ifs);
}
else if (line == "[PARTICLE]") {
CParticle* p = new CParticle();
p->readObject(ifs);
}
...
Моя проблема возникает с тем, как обрабатывать определенные пользователем классы, т.е. классы игры, в которых используется игровой движок. Базовый класс имеет абстрактный метод readObject
, поэтому все, что наследует, должно реализовать этот метод.
Вопрос в том, как синтаксический анализатор узнает о новом классе? Например, у меня есть CVehicle
класс анализатор теперь нужно будет знать, чтобы признать «[АВТОМОБИЛЬ]», а также быть в состоянии создать new CVehicle
Есть ли способ хранить тип класса или что-то в массиве/карте, так возможно, у меня могла бы быть функция регистрации списка типов классов со строками, чтобы обеспечить поиск для создания новых экземпляров?
бит длинного кадра и не может быть возможным, так что если у кого есть другие предложения о том, как подойти к синтаксический они будут приветствоваться
привет, спасибо за информативный ответ. Я попробую и посмотрю, как это происходит. – Zammalad
OK Мне нравится этот подход, так как это означает, что я могу сделать полный скрипт-читатель более универсальным и добавить даже внутренние скриптовые расширения, добавив новые движки игры. Однако я попытался реализовать и решить одну проблему. Это с частью 'CMyCustomClass :: GetClass()'. Если я попытаюсь передать его в соответствии с вашим примером, компилятор завершит с ошибкой «Невозможно инициализировать параметр типа« CBaseClass * (*)() »с lvalue типа« CFont *() »: другой тип возврата (« CBaseClass * vs 'CFont *') " – Zammalad
Я исправил свою проблему. Простая ошибка в том, что я передал указатель на новый класс клиента 'CFont' в этом случае вместо того, чтобы передавать его указатель базового класса – Zammalad