Как я могу добавить отражение в приложение C ++? - PullRequest
228 голосов
/ 03 сентября 2008

Я хотел бы иметь возможность проанализировать класс C ++ на предмет его имени, содержимого (то есть членов и их типов) и т. Д. Я говорю здесь на родном C ++, а не на управляемом C ++, который имеет отражение. Я понимаю, что C ++ предоставляет некоторую ограниченную информацию, используя RTTI. Какие дополнительные библиотеки (или другие методы) могут предоставить эту информацию?

Ответы [ 32 ]

9 голосов
/ 23 июля 2014

В C ++ есть еще одна новая библиотека для отражения, которая называется RTTR (тип времени отражения, см. Также github ).

Интерфейс похож на отражение в C # и работает без каких-либо RTTI.

9 голосов
/ 03 сентября 2008

Два похожих на рефлексии решения, которые я знаю по моим дням в C ++:

1) Используйте RTTI, который предоставит вам загрузчик для построения вашего поведения, похожего на отражение, если вы в состоянии заставить все ваши классы наследовать от базового класса 'object'. Этот класс может предоставлять некоторые методы, такие как GetMethod, GetBaseClass и т. Д. Что касается работы этих методов, вам нужно будет вручную добавить несколько макросов для украшения ваших типов, которые за кулисами создают метаданные в типе для предоставления ответов на GetMethods и т. Д.

2) Другой вариант, если у вас есть доступ к объектам компилятора, это использовать DIA SDK . Если я правильно помню, это позволяет вам открывать pdbs, которая должна содержать метаданные для ваших типов C ++. Этого может быть достаточно, чтобы сделать то, что вам нужно. Эта страница показывает, как вы можете получить все базовые типы класса, например.

Оба эти решения немного уродливы! Нет ничего лучше, чем немного C ++, чтобы вы могли оценить роскошь C #.

Удачи.

7 голосов
/ 04 ноября 2012

Отражение не поддерживается C ++ из коробки. Это печально, потому что это делает оборонительное испытание болью.

Существует несколько подходов к рефлексии:

  1. использовать отладочную информацию (не переносимо).
  2. Обсыпайте ваш код макросами / шаблонами или другим исходным подходом (выглядит некрасиво)
  3. Измените компилятор, такой как clang / gcc, для создания базы данных.
  4. Использовать подход Qt moc
  5. Повышение отражения
  6. Точное и плоское отражение

Первая ссылка выглядит наиболее многообещающе (использует мод для лязга), вторая обсуждает ряд методов, третья - это другой подход с использованием gcc:

  1. http://www.donw.org/rfl/

  2. https://bitbucket.org/dwilliamson/clreflect

  3. https://root.cern.ch/how/how-use-reflex

Сейчас существует рабочая группа для отражения C ++. Смотрите новости для C ++ 14 @ CERN:

Изменить 13/08/17: Начиная с оригинального поста было много потенциальных улучшений в рефлексии. Ниже приводится более подробная информация и обсуждение различных методов и статуса:

  1. Статическое отражение в двух словах
  2. Статическое отражение
  3. Конструкция для статического отражения

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

Ниже приведена подробная информация о текущем состоянии на основе отзывов с последнего совещания по стандартам C ++:

Изменить 13/12/2017

Отражение, похоже, движется к C ++ 20 или, более вероятно, к TSR. Движение однако медленное.

Редактировать 15/09/2018

Проект ТС был разослан в национальные органы для голосования.

Текст можно найти здесь: https://github.com/cplusplus/reflection-ts

7 голосов
/ 29 октября 2013

РЕДАКТИРОВАТЬ: Обновленная неработающая ссылка по состоянию на 7 февраля 2017 года.

Думаю, никто не упомянул об этом:

В CERN они используют систему полного отражения для C ++:

ЦЕРН Рефлекс . Кажется, это работает очень хорошо.

6 голосов
/ 12 ноября 2010

Этот вопрос сейчас немного стар (не знаю, почему я продолжаю задавать старые вопросы сегодня), но я думал о BOOST_FUSION_ADAPT_STRUCT , который вводит отражение во время компиляции.

Вы, конечно, можете сопоставить это с отражением во время выполнения, и это будет не слишком легко, но это возможно в этом направлении, хотя и не будет наоборот:)

Я действительно думаю, что макрос для инкапсуляции BOOST_FUSION_ADAPT_STRUCT может генерировать необходимые методы для получения поведения во время выполнения.

6 голосов
/ 24 ноября 2008

Думаю, вам может быть интересна статья Доминика Филиона "Использование шаблонов для отражения в C ++". Он находится в разделе 1.4 Gems для программирования игр 5 . К сожалению, у меня нет своей копии, но поищите ее, потому что я думаю, что она объясняет то, что вы просите.

4 голосов
/ 30 декабря 2010

Отражение - это, по сути, то, что компилятор решил оставить в виде следов в коде, который может запросить код времени выполнения. C ++ славится тем, что не платит за то, что вы не используете; Поскольку большинство людей не используют / не хотят отражать, компилятор C ++ избегает затрат, не записывая что-либо .

Таким образом, C ++ не обеспечивает рефлексию, и не так просто «имитировать» его как общее правило, как отмечали другие ответы.

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

Наш инструментарий реинжиниринга программного обеспечения DMS - это обобщенная технология компиляции, параметризованная явными определениями языка. Он имеет языковые определения для C, C ++, Java, COBOL, PHP, ...

Для версий C, C ++, Java и COBOL он обеспечивает полный доступ к деревьям разбора и информации таблицы символов. Эта информация таблицы символов включает в себя данные, которые вы, вероятно, захотите получить от «отражения». Если ваша цель состоит в том, чтобы перечислить некоторый набор полей или методов и сделать что-то с ними, DMS можно использовать для преобразования кода в соответствии с тем, что вы найдете в таблицах символов произвольным образом.

4 голосов
/ 31 декабря 2015

Ponder - библиотека отражений C ++, в ответ на этот вопрос. Я рассмотрел варианты и решил сделать свои собственные, так как я не мог найти тот, который отмечал бы все мои коробки.

Хотя на этот вопрос есть отличные ответы, я не хочу использовать тонны макросов или полагаться на Boost. Boost - отличная библиотека, но есть множество небольших проектов C ++ 0x, которые проще и быстрее компилируются. Существуют также преимущества возможности внешнего декорирования класса, например, обертывание библиотеки C ++, которая (пока?) Не поддерживает C ++ 11. Это форк CAMP, использующий C ++ 11, что больше не требует Boost .

3 голосов
/ 28 июля 2011

Вы можете найти другую библиотеку здесь: http://www.garret.ru/cppreflection/docs/reflect.html Он поддерживает 2 способа: получить информацию о типе из отладочной информации и позволить программисту предоставить эту информацию.

Я также заинтересовался отражением для своего проекта и нашел эту библиотеку, я еще не пробовал ее, но пробовал другие инструменты этого парня, и мне нравится, как они работают: -)

3 голосов
/ 06 апреля 2013

Ознакомьтесь с Classdesc http://classdesc.sf.net. Он обеспечивает отражение в виде "дескрипторов" класса, работает с любым стандартным компилятором C ++ (да, известно, что он работает как с Visual Studio, так и с GCC) и не требует аннотация исходного кода (хотя существуют некоторые прагмы для обработки сложных ситуаций). Он разрабатывался более десяти лет и использовался в ряде проектов промышленного масштаба.

...