2016-08-02 3 views
-1

Я пытаюсь узнать, как сериализовать объекты C++. После прочтения нескольких сообщений здесь неплохо использовать функции сериализации boost и архивирование с использованием функций загрузки/сохранения. Однако я бы хотел избежать использования библиотеки boost.Сериализовать объект C++, не зная его полей

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

Может использовать stringstream и перегружать оператор << для преобразования объекта в строку, могу ли я непосредственно сохранить объект.

Спасибо, К.

+2

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

+1

Кто-то должен знать свои поля, возможно, сам. Вы можете сделать это так, чтобы вызывающему абоненту не нужно было знать поля и что есть одна функция для чтения и записи. Обратите внимание, что сериализация имеет множество тернистых проблем, таких как управление версиями и т. П., Которые делают сомнения в том, что библиотеки одного размера подходят для всех. – Yakk

ответ

1

Концептуально, можно сохранить объект, не зная его полей.

Нет, вы не можете.

Без отражения в C++ единственным способом хранения объекта является знание всех его членов класса.

Да. Лучше оставить это знание, инкапсулированное в этом самом классе:

class MyClass { 
public: 
    std::ostream& put(std::ostream& os) const { 
     os << field1 << " " << field2 << std::endl; 
     return os; 
    } 
    friend std::ostream& operator<<(std::ostream& os, const MyClass& myclass) { 
     return myClass.put(os); 
    } 
private: 
    int field1; 
    double field2; 
}; 
+0

Мне не нравится этот дизайн, потому что чтение пишет нарушает сухость. Добавьте шаблон-помощник и получите io одну функцию с чтением прочитанной версии и записью написания версии, чтобы улучшить ситуацию. – Yakk

+0

@Yakk Вы всегда можете добавить больше уровней косвенности, что не мешает вам знать, что существуют фактические поля (здесь QED). –

+0

Это очень сложно усложнить (например, представьте, если класс имел строковое поле) - я думаю, что лучше реализовать 'put', вызвав вспомогательную функцию для каждого именованного члена, а помощник перегружен, чтобы поддерживать любые типы членов, которые вы будет использовать –

0

подхода вы можете следовать, чтобы поддерживать кортежи-симпатии и итерируемые по умолчанию.

Есть read_archive и write_archive, что первым делает фантазии SFINAE для обнаружения типов, которые поддерживают for(:) циклов и типов, кортеж, как и в том, что они поддерживают std::tuple_size и ADL get<I>.

Это также относится к одной форме структурированной привязки в C++ 17.

Далее, введите to_tie sfinae adl, основанный на использовании, который проверяет to_tie() и to_tie(.). Если это так и доступно для чтения/записи, это использует.

Возможно, где-то там есть adl-поиск функции archive_io, поэтому вы можете явно написать свой собственный io.

Целью является автоматическое архивирование как можно больше, и с чем вы не можете легко скомпоновать.

Смежные вопросы