QT序列化QList

需求:一个进程需要将QList中保存的数据序列化后发送到另一个进程,另一个进程将收到的数据反序列化为QList后使用

方案:使用 QDataStream 配合 QByteArray来进行序列化,然后将QByteArray发送到对端

情景1: QList<obj>    QList中每个元素是一个对象

说明:QList<obj>的使用方式存在性能问题,例如向队列中插入一个对象时,需要拷贝构造一个临时对象,将临时对象插入到list中;再比如:foreach(T t, list) 遍历时,每次也需要高考构造一个临时对象t

class CSubTest {  // 这里不能继承QObject, 如果继承,无法使用foreach遍历,因为QObject禁止拷贝构造
public:
    qint32 m_x;
    qint32 m_y;


    friend QDataStream& operator<<(QDataStream& out, const CSubTest& obj)
    {
        out << obj.m_x << obj.m_y;
        return out;
    }


    friend QDataStream& operator>>(QDataStream& in, CSubTest& obj)
    {
        in >> obj.m_x >> obj.m_y;
        return in;
    }
};


class CTest:public QObject{
    Q_OBJECT
public:
    qint32 m_x;
    qint32 m_y;
    QList<CSubTest> m_z;

    friend QDataStream& operator<<(QDataStream& out, const CTest& obj)
    {
        out << obj.m_x << obj.m_y << obj.m_z;
        return out;
    }


    friend QDataStream& operator>>(QDataStream& in, CTest& obj)
    {
        in >> obj.m_x >> obj.m_y >> obj.m_z;
        return in;
    }
};


测试代码:
    CTest test;
    test.m_x = 1;
    test.m_y = 2;

    CSubTest subTest1;
    subTest1.m_x = 11;
    subTest1.m_y = 12;

    CSubTest subTest2;
    subTest2.m_x = 21;
    subTest2.m_y = 22;

    test.m_z.append(subTest1);
    test.m_z.append(subTest2);

    QByteArray byteArray;
    QDataStream out(&byteArray, QIODevice::WriteOnly);
    out << test;

    QDataStream in(byteArray);
    CTest test1;
    in >> test1;

    qInfo("test1.m_x=%d; test1.m_y=%d", test1.m_x, test.m_y);
    foreach(CSubTest tmp, test.m_z)
    {
        qInfo("tmp.m_x=%d; tmp.m_y=%d", tmp.m_x, tmp.m_y);
    }

输出:
    Info: test1.m_x=1; test1.m_y=2
    Info: tmp.m_x=11; tmp.m_y=12
    Info: tmp.m_x=21; tmp.m_y=22

情景2: QList<obj*>    QList中每个元素是一个对象指针

class CSubTest:public QObject {
    Q_OBJECT
public:
    qint32 m_x;
    qint32 m_y;

    friend QDataStream& operator<<(QDataStream& out, const CSubTest& obj)
    {
        out << obj.m_x << obj.m_y;
        return out;
    }

    friend QDataStream& operator>>(QDataStream& in, CSubTest& obj)
    {
        in >> obj.m_x >> obj.m_y;
        return in;
    }
};

class CTest:public QObject{
    Q_OBJECT
public:
    qint32 m_x;
    qint32 m_y;
    QList<CSubTest*> m_z;

    friend QDataStream& operator<<(QDataStream& out, const CTest& obj)
    {
        out << obj.m_x << obj.m_y;

        qint32 m_z_size = obj.m_z.size();  // 这里是关键,将数组个数也序列化;接收端才能知道list中有多少个对象
        out << m_z_size;
        foreach(CSubTest* tmp, obj.m_z)
        {
            out << *tmp;   // tmp是指针,*tmp将对象中的数据序列化
        }
        return out;
    }

    friend QDataStream& operator>>(QDataStream& in, CTest& obj)
    {
        in >> obj.m_x >> obj.m_y;

        qint32 m_z_size;
        in >> m_z_size;

        for (int i = 0; i < m_z_size; i++)
        {
            CSubTest* tmp = new CSubTest;
            in >> *tmp;
            obj.m_z.append(tmp);
        }
        return in;
    }
};

测试代码:
    CTest test;
    test.m_x = 1;
    test.m_y = 2;

    CSubTest* subTest1 = new CSubTest;
    subTest1->m_x = 11;
    subTest1->m_y = 12;

    CSubTest* subTest2 = new CSubTest;
    subTest2->m_x = 21;
    subTest2->m_y = 22;

    test.m_z.append(subTest1);
    test.m_z.append(subTest2);

    QByteArray byteArray;
    QDataStream out(&byteArray, QIODevice::WriteOnly);
    out << test;

    QDataStream in(byteArray);
    CTest test1;
    in >> test1;

    qInfo("test1.m_x=%d; test1.m_y=%d", test1.m_x, test.m_y);
    foreach(CSubTest* tmp, test.m_z)
    {
        qInfo("tmp.m_x=%d; tmp.m_y=%d", tmp->m_x, tmp->m_y);
    }

 

Qt中,可以使用QDataStream类来实现对象的序列化反序列化序列化是将对象转换为字节流的过程,而反序列化则是将字节流转换回对象的过程。 要进行序列化,首先需要创建一个QFile对象,并以只写模式打开文件。然后,创建一个QDataStream对象,并将其与文件关联起来。接下来,可以使用QDataStream的<<操作符将对象写入到数据流中。例如,可以使用out << QString("hello world!");将字符串写入数据流中。 要进行反序列化,需要创建一个QFile对象,并以只读模式打开文件。然后,创建一个QDataStream对象,并将其与文件关联起来。接下来,可以使用QDataStream的>>操作符从数据流中读取对象。例如,可以使用in >> str;将字符串从数据流中读取出来。 对于自定义类或数据结构的序列化反序列化,需要在自定义类中声明并实现友元函数。友元函数可以访问类的私有成员,并将对象的数据写入或读取到数据流中。 需要注意的是,QDataStream只能序列化基本类型,对于其他类型,如自定义类或数据结构,需要在类中声明并实现友元函数。友元函数的声明和实现分别使用<<和>>操作符。 QDataStream支持的数据类型包括bool、qint8、qint16、qint32、qint64、quint8、quint16、quint32、quint64、float、double、const char*、QBitArray、QBrush、QByteArray、QColor、QCursor、QDate、QDateTime、QEasingCurve、QFont、QGenericMatrix、QHash<Key, T>、QIcon、QImage、QKeySequence、QLinkedList<T>、QList<T>、QMap<Key, T>、QMargins、QMatrix4x4、QPair<T1, T2>、QPalette、QPen、QPicture、QPixmap、QPoint、QQuaternion、QRect、QRegExp、QRegularExpression、QRegion、QSize、QString、QTime、QTransform、QUrl、QVariant、QVector2D、QVector3D、QVector4D、QVector<T>等多种类型。[1][2][3]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值