Создание членов-классов на лету

181
15 декабря 2016, 16:04

Всех с новым годом, господа, и сразу из-под ёлки к делу. Пишу программу, которая будет работать с несколькими файлами структурированных данных. Забегая на перед, обобщу: по идее должно получиться некое недо-СУБД. До вскрытия файла/таблицы типы и размеры записей/полей неизвестны. Вот пятой точкой чую, что в C++ можно на лету создавать классы и структуры ну или как минимум их члены. Подскажите, как это делается, ну или хотя бы как это называется?

Answer 1

А как потом к этим именам обращаться будете? В с++ все имена переменных и функций должны быть известны на момент компиляции.

Но давайте подумаем, что подобное возможно. И я показал некий синтаксис, который это позволяет сделать. Тогда сразу возникнет ещё пара вопросов. Как узнать список переменных некоторого класса (их имена, количество) и как обращаться к ним по имени. Это конечно частично решается использованием rtti, но будет костыль на костыле. А код будет жуткий. А ещё появиться вопрос в том, как отличать функции/переменные собственные от тех, которые пришли от полей базы.

Поэтому обычно это решают по другому. Делают один класс, у которого есть переменная

std::map<string, Field> fields;

Узнать кол-во полей просто - это просто список ключей.

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

class Field {
  public
    int getFiledType(); // тут можно и enum использовать
    int getInt(); // возвратить значения поля в виде int
    std::string getString(); // возвратить поле в виде строки
    bool getBool();
    //....
}

а в наследниках переопределяем правильно методы. К примеру, класс для строкового поля в функции getString просто возвращает значение, а в getInt либо пытается преобразовать в число, либо просто "бросает исключение". Класс для работы с числовыми полями преобразовать в строку всегда сможет - тут немного легче. Можно условиться, что getString обязаны реализовать все наследники и не генерировать исключения.

У меня когда то была очень похожая задача. Нужно было генерировать классы на основании json файлов. Я написал скрипт на перл, который читал исходные файлы, делал анализ (угадывал типы полей) и генерировал .сpp/.h файлы. В них было много "метаинформации". Поэтому, если мне нужно было получить список всех полей, которые возвращают целое, то я просто доделывал генератор и получал специальную новую функцию, которая возвращала нужный список. Также там было много-много макросов, что бы не было много однотипного кода. Этот скрипт был включен в make файл и все было относительно прозрачно для компилятора.

Answer 2

Дальнейшие изыскания привели к следующим выяснениям: 1)Моя пятая точка меня подвела.
2)Запрашиваемое явление именуется "Динамический класс" и в c++ места не имеет. Во всяком случает на прямую реализация вроде как противоречит самой ООП-парадигме языка. 3)"Бубен для программирования" надо помещать в раздел "экзотических игрушек" секс-шопа. Ибо между "кодо-шаманизмом" и "сексом с кодом" я вижу много аналогий.

READ ALSO
Из-за DebugActiveProcess зависает вся система!

Из-за DebugActiveProcess зависает вся система!

После использования DebugActiveProcess() раз в несколько секунд подвисает вся сисетмаПроцесс, к которому подключаюсь, не системный! Не могу разобрать,...

159
Структура данных для z-index

Структура данных для z-index

Необходимо подобрать структуру данных для хранения данных z-indexВсе индексы должны быть уникальными и для них должна быть определена операция...

142
Не видит идентификаторов в main из класса

Не видит идентификаторов в main из класса

Вроде все правильно, почему так? Что забыл? Не видит device, driver, smgr, guienv, camera, skybox, font

187
Бинарная запись в файл

Бинарная запись в файл

Здравствуйте! Можно ли организовать бинарную запись в файл также как текстовую? Например:

237