Реализация отражения: Как найти родителя класса - PullRequest
3 голосов
/ 28 февраля 2012

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

Однако я бы хотелбудь здесь как можно более минималистичным.Итак, после изучения некоторых существующих реализаций я нашел подходящую мне концепцию.Для упрощения шаблон выглядит следующим образом:

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);
};

, тогда я бы хотел избежать указания Base и все еще иметь возможностьпопасть в RTTI своих членов.Я надеялся, что у Base есть какой-то способ скрыть некоторые подсказки в его RTTINFO(...) для Derived, чтобы сделать это возможным.Итак ... есть ли?

Основные требования:

  1. Я не хочу указывать базовый класс нигде, кроме места, определенного языком.И я не хочу помещать class Derived : public Base в любой макрос.
  2. RTTIINFO может добавить любой необходимый язык и смещение памяти для затронутого класса.
  3. Я могу поместить все, что захочуМакрос RTTINFO, даже тонны кода, если необходимо.
  4. И Base, и Derived используют один и тот же макрос RTTINFO, который, конечно, может быть повторно использован при дальнейшем наследовании.Оставим в стороне проблему множественного наследования, одиночное наследование кажется достаточно сложным.
  5. Для Derived необязательно иметь доступ к RTTI Base, это может быть любой другой внешний вспомогательный класс / функция, который будет обрабатыватьДанные RTTI.Однако частные переменные-члены должны поддерживаться.
  6. Я не возражаю против затрат на компиляцию и время выполнения - если какие-либо вычисления, такие как построение дерева наследования, опрос всех существующих классов, что угодно, должны выполняться во время выполнения,всегда есть способ, с помощью которого я мог бы переместить его на этап инициализации программы, поэтому для меня это не имеет большого значения.
  7. Если возможно, избегайте RTTI с поддержкой языков, так как в некоторых проектах его нужно отключать.Во всяком случае, я не нашел решения даже с ним.
  8. Никакой дополнительный шаг компиляции не может быть добавлен.

Одно примечание: возможно, я мог бы использовать type_info::before(), но даже если этобудет работать для обычных компиляторов, стандарт C ++ говорит, что я не могу здесь полагаться на отношения наследования.

Спасибо за любые предложения!

Andrew

Ответы [ 2 ]

3 голосов
/ 28 февраля 2012

У вас не будет полного отражения с текущими компиляторами C ++ 03 или C ++ 11 (потому что даже C ++ 11 не имеет реального отражения).

Вы можете создать некоторый мета-класскод (посмотрите на Qt MOC в качестве хорошего примера)

Вы можете расширить свой компилятор C ++.Если это GCC, рассмотрите возможность создания плагина или расширения MELT .

2 голосов
/ 28 февраля 2012

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

И как C ++имеет истинное множественное наследование, у вас есть возможность преодолеть этот недостаток и вывести свои поведенческие классы из сгенерированных.

Stefan

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...