У меня здесь есть проблема. Я работаю над библиотекой отражений, как с упражнениями, так и с утилитами для будущих проектов. Чтобы заставить его работать, я уже согласился с тем, что неизбежно быть навязчивым, и мне нужно будет добавить, по крайней мере, немного кода для тела класса, чтобы получить ценные данные отражения.Реализация рефлексии: как найти родителя класса
Однако я хотел бы быть как можно более минималистичным. Итак, изучив некоторые существующие реализации, я нашел концепцию, которая мне подходит. Для упрощения, картина выглядит следующим образом:
class Base
{
int baseFoo;
double baseBar[5];
RTTINFO(baseFoo, baseBar);
};
(...)
Base sth;
std::cout << TypeInfo(sth).variables[0].name; << std::endl;
// I don't mind if the way of accessing the type info changes totally
Используя некоторые общие программирования, я могу достичь в значительной степени скрывается что-то мне нравится за этим RTTINFO
макро и построения информационного типа структур. Я могу получить типы, имена, размер массива и т.д. Но когда я хочу пойти на один шаг дальше и ввести наследование, например:
class Derived : public Base
{
std::string foo;
char* bar;
/* RTTIPARENT(Base); <-- I want to avoid this */
RTTINFO(foo, bar);
};
, то я бы хотел, чтобы избежать базы и задав все еще быть в состоянии получить в его RTTI членов. Я надеялся, что есть некоторая дорога для Base
, чтобы пронести какие-то намеки в ее RTTINFO(...)
за Derived
, чтобы сделать это возможным. Так .. есть?
Основные требования:
- Я не хочу, чтобы указать базовый класс в любом месте, но язык определенные места. И я не хочу обертывать
class Derived : public Base
в любом макросе. RTTIINFO
может добавить к затронутому классу любые смещения языка и памяти.- Я могу положить все, что захочу, в
RTTINFO
макрос, даже тонны кода при необходимости. - И базовый, и производный используют тот же самый
RTTINFO
макрос, который может быть использован повторно в дальнейшем, конечно. Оставим проблему множественного наследования, одно наследование кажется достаточно сложным. - Для доступа к RTTI
Base
Derived
, это может быть любой другой внешний вспомогательный класс/функция, которая будет обрабатывать данные RTTI. Однако необходимо поддерживать частные переменные-члены. - Я не возражаю против затрат на компиляцию и время исполнения - если какие-либо вычисления, такие как построение дерева наследования, опрос всех существующих классов, что бы то ни было, должны выполняться во время выполнения, всегда можно переместить его на этап инициализации программы, так что для меня это не очень важно.
- Если возможно, избегайте RTTI с поддержкой языков, поскольку я должен быть отключен в некоторых проектах. Во всяком случае, я не нашел решения даже с ним.
- Дополнительный этап компиляции не может быть добавлен.
Одно примечание: Может быть, я мог бы использовать type_info::before()
, но даже если она будет работать для обычных компиляторов, стандарт C++ говорит, что я не могу полагаться на наследование отношений здесь.
Спасибо за любые предложения!
Andrew
Как получить текущее имя класса в макросе? –
Reflection принадлежит к вашему C + + «Утилите для будущего», так как бензопила принадлежит к практике дантиста. –
Точно, если вы хотите получить какую-либо информацию о отражении/типе, у вас будет столько макросов, что это будет бесполезно. Просто посмотрите на GObject – farnoy