基于qt实现的类的序列化和反序列化

时间:2024-03-12 20:33:04

一种可行的方法是使用元编程(例如模板元编程)来自动生成序列化和反序列化的代码。只需要为每个类提供成员变量的定义,然后使用元编程来生成相应的序列化和反序列化代码。这样可以大大减少手动编写的代码量,并且保持代码的整洁性。

#include <QDataStream>
#include <QString>
#include <QDebug>

// Serialize data
template<typename T>
void serializeData(QDataStream& stream, const T& data) {
    stream << data;
}

// Deserialize data
template<typename T>
void deserializeData(QDataStream& stream, T& data) {
    stream >> data;
}

// Serialize a struct/class
template<typename T>
void serialize(QDataStream& stream, const T& obj);

// Deserialize a struct/class
template<typename T>
void deserialize(QDataStream& stream, T& obj);

// Helper to serialize and deserialize data members
#define SERIALIZE_MEMBER(member) serializeData(stream, obj.member);
#define DESERIALIZE_MEMBER(member) deserializeData(stream, obj.member);

// Macro to define serialization and deserialization methods
#define DECLARE_SERIALIZE(ClassType, ...) \
    template<> \
    void serialize<QDataStream>(QDataStream& stream, const ClassType& obj) { \
        __VA_ARGS__ \
    } \
    template<> \
    void deserialize<QDataStream>(QDataStream& stream, ClassType& obj) { \
        __VA_ARGS__ \
    }

// Example class with serialization and deserialization support
class MyClass {
public:
    int value;
    QString name;

    // Define serialization and deserialization
    DECLARE_SERIALIZE(MyClass,
        SERIALIZE_MEMBER(value)
        SERIALIZE_MEMBER(name)
    )
};

int main() {
    // Create an instance of MyClass
    MyClass originalObj;
    originalObj.value = 42;
    originalObj.name = "Hello, World!";

    // Serialize the object
    QByteArray byteArray;
    QDataStream out(&byteArray, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5);
    serialize(out, originalObj);

    // Deserialize the object
    MyClass newObj;
    QDataStream in(byteArray);
    in.setVersion(QDataStream::Qt_5);
    deserialize(in, newObj);

    // Check if deserialization was successful
    qDebug() << "Value:" << newObj.value;
    qDebug() << "Name:" << newObj.name;

    return 0;
}

另一种方法是使用宏来简化序列化和反序列化的过程。可以定义一组宏来生成相应的序列化和反序列化代码。虽然宏可能会使代码看起来更加复杂,但可以有效地减少重复性代码的编写。

#include <QDataStream>
#include <QString>
#include <QDebug>

// Define a macro to serialize a member
#define SERIALIZE_MEMBER(member) stream << obj.member;

// Define a macro to deserialize a member
#define DESERIALIZE_MEMBER(member) stream >> obj.member;

// Define a macro to declare serialization and deserialization methods for a class
#define DECLARE_SERIALIZE(ClassType, ...) \
    friend QDataStream& operator<<(QDataStream& stream, const ClassType& obj) { \
        __VA_ARGS__ \
        return stream; \
    } \
    friend QDataStream& operator>>(QDataStream& stream, ClassType& obj) { \
        __VA_ARGS__ \
        return stream; \
    }

class MyClass {
public:
    int value;
    QString name;

    // Declare serialization and deserialization methods using macros
    DECLARE_SERIALIZE(MyClass,
        SERIALIZE_MEMBER(value)
        SERIALIZE_MEMBER(name)
    )
};

int main() {
    // Create an instance of MyClass
    MyClass originalObj;
    originalObj.value = 42;
    originalObj.name = "Hello, World!";

    // Serialize the object
    QByteArray byteArray;
    QDataStream out(&byteArray, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5);
    out << originalObj;

    // Deserialize the object
    MyClass newObj;
    QDataStream in(byteArray);
    in.setVersion(QDataStream::Qt_5);
    in >> newObj;

    // Check if deserialization was successful
    qDebug() << "Value:" << newObj.value;
    qDebug() << "Name:" << newObj.name;

    return 0;
}

 比较喜欢第二种实现