В отличие от Java или C #, C ++ не имеет функции самоанализа / отражения вне информации о типе времени выполнения (RTTI), которая имеет различную направленность и ограничена полиморфными объектами.Это означает, что за пределами нестандартного прекомпилятора вы должны будете так или иначе сообщить платформе сериализации, как структурирован ваш объект и как вы в конечном итоге хотели бы отобразить его в иерархию int
, std::string
и другие основные типы данных.Я обычно различаю три разных подхода: прекомпилятор, встроенная спецификация, преобразование свойств.
Прекомпилятор. Хорошим примером прекомпиляторного подхода является буфер протокола Google: https://developers.google.com/protocol-buffers/docs/cpptutorial. Вы определяете свои сущности в отдельном файле .proto
, который преобразуется с помощью проприетарного компилятора в .c
и .h
классы сущностей.Эти классы могут использоваться как обычные объекты POCO и могут быть сериализованы с использованием буферов протокола.
Встроенная спецификация: Повышенная сериализация (https://www.boost.org/doc/libs/1_67_0/libs/serialization/doc/index.html), s11n (www.s11n.net) иrestc-cpp (https://github.com/jgaa/restc-cpp) - примеры явного указания структуры ваших POCO для каркаса внутри вашего собственного кода. API для этого может быть более или менее сложным, но принцип, лежащий в основе этого, всегда один и тот же:Вы предоставляете реализации serialise
/ deserialise
для своих классов или регистрируете информацию метаданных, которая позволяет платформе генерировать их. Пример ниже от restc-cpp:
struct Post {
int userId = 0;
int id = 0;
string title;
string body;
};
BOOST_FUSION_ADAPT_STRUCT(
Post,
(int, userId)
(int, id)
(string, title)
(string, body)
)
Преобразование свойств: последний вид сериализации, о котором я не хочу пропустить, это явное преобразование в промежуточный тип данных, предоставляемый платформой.Хорошие примеры этого подхода - дерево свойств повышения (
https://www.boost.org/doc/libs/1_67_0/doc/html/property_tree.html) и JsonCpp (
http://open -source-parsers.github.io / jsoncpp-docs / doxygen / index.html ).отвечает за реализацию преобразования ваших собственных типов в
ptree
, который Boost может сериализовать в любой формат, который вам нравится (XML, JSON).
Имея свой опыт работы со всеми тремя подходамив C ++ я бы по умолчанию порекомендовал вариант 3. Похоже, что он хорошо соответствует модели POCO C ++ Parser
и Var
для JSON. Одним из вариантов является то, что все классы POCO вашей сущности реализуют to_var
или from_var
или вы можете сохранить эти функции сериализации в отдельном пространстве имен для каждого класса POCO, так что их нужно включать только при необходимости.
Если вы работаете над проектами, для которых сериализуется значительное количество объектов (например, сообщения в коммуникационных библиотеках), опция предварительной компиляции может стоить первоначальной установки и дополнительной сложности сборки, но это зависит, каквсегда, о конкретном проекте, с которым вы имеете дело.