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

Рейтинг: 0Ответов: 2Опубликовано: 02.01.2015

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

Ответы

▲ 2

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

Но давайте подумаем, что подобное возможно. И я показал некий синтаксис, который это позволяет сделать. Тогда сразу возникнет ещё пара вопросов. Как узнать список переменных некоторого класса (их имена, количество) и как обращаться к ним по имени. Это конечно частично решается использованием 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 файл и все было относительно прозрачно для компилятора.

▲ 1

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