Если я преобразовал член структуры типа int в char * для его сериализации, должен ли я преобразовать его как тип int * при десериализации? - PullRequest
1 голос
/ 25 мая 2020

Дата структуры имеет два типа int, для которых функция записи структуры использует reinterpret_cast<char*>() для хранения ее на диске. Чтобы снова прочитать его с диска и сохранить как переменную int структуры, не следует ли мне reinterpret_cast переменную int day как <int*> правильно сохранить? Примерно так:

os.write(reinterpret_cast<char*>(&day),sizeof(day)); //to cast it into char* to store it in file

и, чтобы десериализовать его так:

is.read(reinterpret_cast<int*>(&day),sizeof(day)); //to cast it into char* to read it from file

вместо:

is.read(reinterpret_cast<char*>(&day),sizeof(day)); //which just converts it back to char* to read from file

Причина в том, что я хочу иметь возможность для выполнения арифметики c на int day.

Вот мой код:

struct date{
    int day;
    string month;
    int year;

    void read(istream &is) // to deserialize date and read it from disk
    {
        is.read(reinterpret_cast<char*>(&day), sizeof(day));
        size_t size;
        if (is.read(reinterpret_cast<char*>(&size), sizeof(size)))
        {
            month.resize(size);
            is.read(&month[0], size);
        }
        is.read(reinterpret_cast<char*>(&year), sizeof(year));
    }

    void write(ostream &os) const //to serialize struct date
    {
        os.write(reinterpret_cast<const char*>(&day), sizeof(day));
        size_t size = month.size();
        os.write(reinterpret_cast<const char*>(&size), sizeof(size));
        os.write(month.c_str(), size);
        os.write(reinterpret_cast<const char*>(&year), sizeof(year));
    }
};

1 Ответ

2 голосов
/ 25 мая 2020

Ваш код и так в порядке, и нет причин беспокоиться о том, что day (или year) будет интерпретироваться как что-либо, кроме int, которое объявлено.

При вызовах is.read и os.write единственное, что вы приводите (к указателю char*), - это переданный адрес переменной day. Это вместе со следующим аргументом (sizeof(day)) указывает этим вызовам на чтение / запись соответствующего количества байтов (char всегда один байт , а оператор sizeof дает размер в байтов ) в / из заданного адреса.

Итак, если (что довольно часто), int составляет 4 байта на вашем компиляторе / платформе, тогда будут прочитаны 4 символа из потока и размещены по заданному адресу - четыре «компонентных» байта целого числа будут помещены в память, назначенную для этого целого числа.

Приведение к char * требуется, потому что STL определяет это функции read() и write() принимают такой указатель. Это потому, что потоки реализуются посимвольно; таким образом, чтобы прочитать любой другой тип переменной, вам нужно привести ее адрес и указать соответствующий размер этого типа.

...