Вопрос

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

Знаешь ли ты какой-нибудь хорошие библиотеки с открытым исходным кодом для C++, который поддерживает контейнеры отражения и атрибутов, а именно:

  • Определение RTTI и атрибутов с помощью макросов
  • Доступ к RTTI и атрибутам через код
  • Автоматическая сериализация атрибутов
  • Прослушивание изменений атрибутов (например.OnValueChanged)
Это было полезно?

Решение

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

XRTTI:

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

ОпенС++:

OpenC++ — это интерфейсная библиотека C++ (лексер+парсер+DOM/MOP) и переводчик исходного кода.OpenC++ позволяет разрабатывать инструменты языка C++, расширения, оптимизацию компилятора для конкретной предметной области и протоколы метаобъектов времени выполнения.

Другие советы

Вот что вы получаете, когда C++ встречается с Reflection:

C++ meets Reflection

Что бы вы ни выбрали, скорее всего, у него будут ужасные макросы, трудный для отладки код или странные шаги сборки.Я видел, как одна система автоматически генерировала код сериализации из PDB-файла DevStudio.

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

Существует новый проект, обеспечивающий отражение на C++, использующий совершенно другой подход: ЛАГЕРЬ. https://github.com/tegesoft/camp

CAMP не использует прекомпилятор, классы/свойства/функции/...объявляются вручную с использованием синтаксиса, аналогичного boost.python или luabind.Конечно, люди могут использовать прекомпилятор, такой как gccxml или open-c++, для создания этого объявления, если они того пожелают.

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

Распространяется по лицензии MIT (ранее LGPL).

Я смотрел на эти вещи довольно долго, но они, как правило, очень деспотичны.Они могут помешать вам использовать наследование или иметь странные конструкторы и т.д. и т.п.В конце концов они оказались слишком обузой, а не удобством.

Этот подход к предоставлению элементов, который я сейчас использую, довольно упрощен и позволяет вам исследовать класс для сериализации или, например, установить все поля с именем «x» в 0.Он также статически определен, поэтому работает очень и очень быстро.Никаких слоев библиотечного кода или создания кода, которые могли бы помешать процессу сборки.Он обобщается на иерархии вложенных типов.

Настройте свой редактор на несколько макросов, чтобы автоматизировать написание некоторых из этих вещей.

struct point
{
     int x;
     int y;

     // add this to your classes
     template <typename Visitor>
     void visit(Visitor v)
     {
         v->visit(x, "x"); 
         v->visit(y, "y");
     }
};


/** Outputs any type to standard output in key=value format */
struct stdout_visitor
{
     template <typename T>
     void visit(const T& rhs)
     {
         rhs.visit(this);
     }

     template <typename Scalar>
     void visit (const Scalar& s, const char* name)
     {
          std::cout << name << " = " << s << " ";
     }
}

Тоже некоторое время смотрел на это.Текущее самое простое решение кажется BOOST_FUSION_ADAPT_STRUCT.Практически, когда у вас есть библиотека/заголовок, вам нужно только добавить поля структуры в макрос BOOST_FUSION_ADAPT_STRUCT(), как последний сегмент кода показывает.Да, у него есть ограничения, о которых упоминали многие другие люди.И он не поддерживает слушателей напрямую.

Другие многообещающие решения, которые я рассмотрел:

  • CAMP и XRTTI/gccxml, однако оба они кажутся препятствием для внедрения зависимости от внешних инструментов в ваш проект.
  • Несколько лет назад я использовал Perl c2ph/pstruct чтобы сбросить метаинформацию с вывода gcc -gstabs, это менее навязчиво, но требует дополнительной работы, хотя у меня это сработало идеально.

Что касается подхода boost/__cxa, то как только вы разберетесь со всеми мелкими деталями, добавлять/изменять структуры или поля будет проще в обслуживании.в настоящее время мы используем его для создания уровня привязки пользовательских типов поверх dbus, для сериализации API и сокрытия деталей транспорта/RPC для подсистемы службы управляемых объектов.

Не общий, но QT поддерживает это через метакомпилятор и находится под лицензией GPL.Из разговора с людьми из QT я понял, что это невозможно на чистом C++, поэтому необходим файл moc.

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

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

Инструментарий автоматического самоанализа/рефлексии.Используйте метакомпилятор, такой как Qt, и добавляйте метаинформацию непосредственно в объектные файлы.Интуитивно понятный и простой в использовании.Никаких внешних зависимостей.Даже позволяют автоматически отражать std::string и затем использовать его в скриптах.Пожалуйста, посетите Я НЕ ЗНАЮ

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top