Вы могли бы быть в состоянии обойтись без него, если такие объекты всегда читаются обратно во время одного и того же выполнения программы, которая их написала (хотя я действительно не рекомендую это). Но если данные в файле должны сохраняться между различными выполнениями программы, то использование необработанных байтов объектов в памяти почти наверняка приведет к значительным проблемам.
Каждый vtable сам генерируется во время компиляции и сохраняется где-то в результирующем исполняемом файле. То, что содержит каждый экземпляр объекта, является просто указателем на соответствующую vtable, и этот указатель не изменяется в течение времени жизни любого данного объекта. (Множественное наследование может быть немного сложнее, но для этого обсуждения эти детали не имеют значения. Указатели по-прежнему постоянны.)
Таким образом, если у объекта есть указатель vtable и вы записываете необработанные байты этого объекта на диск, то указатель vtable также записывается на диск. Если вы затем прочитаете эти байты во время одного и того же выполнения программы и вставите их в соответствующий объект, он может работать, поскольку виртуальная таблица будет по-прежнему находиться в том же месте и, следовательно, указатель виртуальной таблицы будет по-прежнему корректным .
(Однако обратите внимание, что все, что я только что объяснил, есть детали реализации. Хотя многие компиляторы обычно реализуют виртуальные функции таким образом, я не думаю, что какие-либо точные детали гарантированы стандартом C ++. Так что могут быть дополнительные потенциальные проблемы.)
Теперь, если это возможно, почему бы не хранить такие объекты в течение более длительного времени? Потому что у вас нет гарантии, что какая-то конкретная виртуальная таблица будет находиться в той же области памяти.
Некоторые операционные системы могут изменять структуру памяти для каждого выполнения одной и той же программы. Я не знаю, действительно ли это влияет на расположение виртуальных столов, но это, безусловно, серьезный риск.
Кроме того, если вы когда-нибудь скомпилируете новую версию программы, расположение каждой виртуальной таблицы полностью зависит от прихоти компилятора. Изменения в, казалось бы, не связанных частях кода могут привести к тому, что компилятор разместит соответствующие виртуальные таблицы в разных местах. Очевидно, что это событие полностью разрушило бы эту схему. И у вас нет способа предотвратить это.
(И помимо vtables, что, если новые элементы данных должны быть добавлены к этим объектам в последующих версиях программы? Возможно, вам придется иметь дело со считыванием предыдущих версий байтов необработанных объектов в новые версии с новыми членами или другой состав членов. Это может быть сложным и уродливым, а также склонным к ошибкам.)
Теперь, даже если вы собираетесь временно хранить объекты для каждого выполнения программы. Я все еще не думаю, что это хорошая идея. Вы сильно ограничены в том, какие переменные могут содержать эти объекты. Нет смарт-объектов (std :: string, std :: vector и т. Д.). Нет указателей на память, выделенную для каждого объекта. Поэтому любые строки должны храниться в необработанных символьных массивах. Другое динамическое распределение должно быть превращено в фиксированные элементы или массивы элементов. Это означает, что вы теряете много преимуществ C ++ везде, где используются эти объекты.
Кроме того, эти объекты и схема записи их непосредственно на диск должны сопровождаться комментариями и документацией, предупреждающими обо всех опасностях, которые я описал. В противном случае, какой-то будущий программист может неосознанно принять решение добавить неправильный тип элемента данных Или, что еще хуже, они могут решить хранить такие объекты дольше, чем при выполнении программы, открывая их для серьезных сбоев и сбоев, которые могут произойти только в будущем (и, вероятно, в самый неподходящий момент).
В конце я настоятельно рекомендую использовать схему, которая хранит данные в формате, специально предназначенном для файла. Как уже упоминалось, Boost Serialization является хорошим вариантом. Если нет, то могут быть другие используемые библиотеки сериализации. Или же, в зависимости от ваших потребностей, вы можете без особых проблем запустить собственный механизм.