Сохранение стуктур довольно распространённая задача, но в тоже её реализация на С++ требует трёх раздельных кусков кода:
- определение типа структуры;
- реализации функции(й) записи структуры в файл;
- реализации функции(й) чтения структуры из файла.
Как следствие, изменение структур ведёт к правке кода в трёх различных местах. Использование функций read и write (и их аналогов из стандартной библиотеки C++) я не рассматриваю по причине сербёзных недостатков такого подхода:
- получаемый файл являтся двоичным и его невозможно править обычными текстовыми редакторами;
- формат файла зависит от компилятора и является потенциально непереносимым на другие процессоры, компиляторы и даже другие версии используемого компилятора;
- изменение структур данных ведёт к изменению формата и для сохранения возможности чтения старых данных требуется принимать дополнительные усилия.
Указанные недостатки отстутствуют у форматов, представляющих данные в виде протого текста. Одним из таких форматов является XML. Для стуктур С++ можно определить ряд соглашений, позволяющих автоматизировать их преобразование из/в XML.
Для моих нужд достаточно преобразования простых стуктур (не содержащих указателей) в XML. Для этого (а также для того чтобы ознакомиться с XSLT) я написал программу, генерирующую по XML-описанию структуры её определение на C++ и функции чтения/записи из/в XML. Описание стуктуры выглядит следующим образом:
<module name="Settings">
<struct name="ReferenceValue"
define="no"
serialize-as="empty-element">
<double name="nominalValue"/>
<double name="minusDelta"/>
<double name="plusDelta"/>
</struct>
<struct name="Foo"
description="A Foo"
property-page="yes">
<int name="a" description="an integer field"/>
<double name="b" description="a double field"/>
<double name="c" dimensions="3,2" description="some array"/>
<int name="d" dimensions="3" description="another array"/>
<instance name="rv" dimensions="2" type="ReferenceValue"/>
</struct>
<struct name="Agg" export-reader='yes' export-writer="yes">
<instance name="foo" type="Foo"/>
</struct>
</module>
