запись структур и классов на диск - PullRequest
0 голосов
/ 22 мая 2010

Следующая функция записывает структуру в файл.

#define PAGESIZE  sizeof(BTPAGE)
#define HEADERSIZE 2L

    int btwrite(short rrn, BTPAGE *page_ptr)
    {
        long addr;
        addr = (long) rrn * (long) PAGESIZE + HEADERSIZE;
        lseek(btfd, addr, 0);
        return (write(btfd, page_ptr, PAGESIZE));
    }

Ниже приведена структура.

typedef struct {
    short keycount;             /* number of keys in page   */
    int  key[MAXKEYS];              /* the actual keys      */
    int  value[MAXKEYS];            /* the actual values        */
    short child[MAXKEYS+1];     /* ptrs to rrns of descendants  */
} BTPAGE;

Что бы произошло, если бы я изменил структуру на класс, она все еще работала бы так же?

Если бы я добавил функции класса, увеличился бы размер, который он занимал бы на диске?

Ответы [ 4 ]

4 голосов
/ 22 мая 2010

Здесь нужно многому научиться.

  • Прежде всего, вы рассматриваете структуру как массив байтов. Это строго неопределенное поведение из-за строгого правила наложения имен . Все может случиться. Так что не делай этого. Вместо этого используйте правильную сериализацию (например, через boost ). Да, это утомительно. Да, это необходимо.
  • Даже если вы игнорируете неопределенность и решаете стать зависимыми от какой-то конкретной реализации компилятора (которая может измениться даже в следующей версии компилятора), все же есть причины этого не делать.
    • Если вы сохраните файл на одном компьютере, а затем загрузите его на другом, вы можете получить мусор, потому что второй компьютер использует другое представление с плавающей запятой или другой порядковый номер , или имеет другой правила выравнивания и др.
    • Если ваша структура содержит какие-либо указатели, весьма вероятно, что при сохранении их дословно, а затем их загрузка приведет к адресу, который не будет указывать на какое-либо значимое место.
  • Обычно, когда вы добавляете функцию-член, это происходит:
    • машинный код функции хранится в месте, совместно используемом всеми экземплярами класса (дублировать его не имеет смысла, поскольку он логически неизменен)
    • скрытый указатель «this» передается в функцию при вызове, поэтому он знает, к какому объекту он был вызван.
    • ничего из этого не требует места для хранения в экземплярах.
  • Однако, когда вы добавляете по крайней мере одну виртуальную функцию, компилятору обычно необходимо также добавить блок данных, называемый vtable (прочитайте его). Это позволяет вызывать другой код в зависимости от текущего типа времени выполнения объекта (он же полиморфизм). Поэтому первая виртуальная функция, которую вы добавляете в класс, вероятно, увеличивает размер объекта.
3 голосов
/ 22 мая 2010

В C ++ разница между struct и class заключается просто в том, что члены и базовые классы структуры являются открытыми по умолчанию, тогда как для класса они являются закрытыми по умолчанию.

Техника простой записи байтов структуры в файл и последующего их считывания снова работает, только если структура представляет собой простые старые данные или POD типа .Если вы измените свою структуру так, чтобы она больше не являлась POD, эта техника не гарантированно сработает (правила, описывающие, что делает структуру POD, перечислены в ответах на связанный вопрос).

1 голос
/ 22 мая 2010

Если у класса есть какая-либо виртуальная функция, значит, у вас проблемы;если нет виртуальных функций, вы все равно должны быть в порядке (конечно, то же самое относится и к структуре, поскольку она тоже может иметь виртуальные функции: разница между структурой и классом заключается лишь в том, что видимость по умолчанию в структуре является общедоступной в классеэто личное).

0 голосов
/ 22 мая 2010

Если вы делаете больше сериализации классов, рассмотрите возможность использования буферов протокола Google или чего-то подобного см. Этот вопрос

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...