CodeBlanks Logo Icon CodeBlanks

Custom serialization

Learn to write your own serialization code.

What is custom serialization?

Custom serialization means you write the serialize and deserialize methods for a struct yourself. You write and read each field in order; this gives full control over the format. It is a flexible blend of the binary and text methods.

Example: struct Point { int x; int y; void serialize(std::ofstream& ofs) const { ofs.write(...); } };. The serialize method is const because it does not modify the object. A separate deserialize(std::ifstream&) method handles reading. This approach makes it easy to add error checking and version logic to serialization.

The deserialize method

The deserialize method reads serialized data back and writes it into the object's fields. It must use the same order as serialize; if the order differs the data is read corrupted.

Example: void deserialize(std::ifstream& ifs) { ifs.read(reinterpret_cast<char*>(&x), sizeof(x)); ifs.read(reinterpret_cast<char*>(&y), sizeof(y)); }. Here serialize wrote x first, so deserialize reads x first. This match is mandatory for data integrity. The two methods work as a pair: one writes, the other reads.

Practice Custom serialization for a Point struct

Define struct Point { int x; int y; void serialize(std::ofstream& ofs) const; };. The serialize method calls ofs.write(reinterpret_cast<const char*>(&x), sizeof(x)) and the same for y. In main create Point p{3, 4}, open an std::ofstream and call p.serialize(ofs). Read back and print std::cout << loaded.x << "," << loaded.y;.

Starter code

main.cpp
#include <iostream>
#include <fstream>

// Define the Point struct and serialize method

int main() {
    // Write the point to a file and read it back
    return 0;
}

Sample solution

main.cpp
#include <iostream>
#include <fstream>

struct Point {
    int x;
    int y;

    void serialize(std::ofstream& ofs) const {
        ofs.write(reinterpret_cast<const char*>(&x), sizeof(x));
        ofs.write(reinterpret_cast<const char*>(&y), sizeof(y));
    }
};

int main() {
    Point p{3, 4};
    std::ofstream ofs("point.bin", std::ios::binary);
    p.serialize(ofs);
    ofs.close();

    Point loaded{0, 0};
    std::ifstream ifs("point.bin", std::ios::binary);
    ifs.read(reinterpret_cast<char*>(&loaded.x), sizeof(loaded.x));
    ifs.read(reinterpret_cast<char*>(&loaded.y), sizeof(loaded.y));
    ifs.close();

    std::cout << loaded.x << "," << loaded.y;
    return 0;
}

Expected output

3,4

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Complete the serialize method

Question
void ____(std::ofstream& out) const {
    out.write(reinterpret_cast<const char*>(&x), sizeof(x));
}
Answer
void serialize(std::ofstream& out) const {
    out.write(reinterpret_cast<const char*>(&x), sizeof(x));
}

Explanation: The serialize method writes the x field in binary.

2 Match each piece to its role

Term Meaning
void serialize(ofs) const Writes
void deserialize(ifs) Reads
const Does not modify object
sizeof(x) Byte size

3 What must serialize and deserialize share?

  • The same operating system
  • The same field order Correct answer
  • The same file name
  • The same compiler

Explanation: serialize and deserialize must use the same field order.

All lessons in Advanced