在Qt中计算对象的序列化大小

Calculate serialization size of objects in Qt

本文关键字:序列化 对象 Qt 计算      更新时间:2023-10-16

我怎么知道 qt 数据类型的大小(以字节为单位);包括 QString 对象(如果这些数据类型是写在某个 QFile 上)。我必须在学生班中实现sizeOf()功能,如下所示;类似于我们在 C 中sizeof(struct student)的东西。

学生班

        #include<QtCore>
        class Student
        {
        public:
            QString name,fname;
            quint8 age,weight,clss;
            Student(){
            }
    /*the following function should return the size of this object in bytes; 
     I will use QDataStream & operator<<(QDataStream &out, Student &f)
     function  to write data to a QFile   */
        qint16 sizeOf()
        {
            // needs implementation;
        }
        };
        QDataStream & operator<<(QDataStream &out, Student &f)
        {
            out<<f.name<<f.fname<<f.age<<f.weight<<f.clss<<f.next;
            return out;

        }
        QDataStream & operator>>(QDataStream &in, Student &f)
        {
            in>>f.name>>f.fname>>f.age>>f.weight>>f.clss>>f.next;
            return in;
        }

我知道数据可以用QDataStream & operator>>(QDataStream &in, Student &f)读取;但我也想知道其他一些情况的大小。

这不会给我一个有效的文件大小。Qt似乎在序列化时增加了一些额外的位;可能是为了不同平台上的字节序独立性。实际大小总是大于sizeOf()函数返回

的大小
qint16 sizeOf()
            {
                qint16 size=0;
                size+=sizeof(quint8)*3; // size of age, weight and clss 
                                        //variables all have type quint8
                size+=name.size()*16;   // number of characters in string
                                         // multiply with 16 bit QChar
                size+=fname.size()*16;
                return size;
            }

我正在使用QFile,QDataStream api。Windows 8上的Qt版本4.8。

sizeof给你的大小并不反映对象可能具有的实际大小。例如,无论实际字符串有多长,32 位构建中的QString sizeof始终为 4 位。

sizeof运算符包括不需要序列化的内容,例如对象的 vtable 指针,并且不考虑为该对象动态分配的资源的大小。

您可以轻松确定可序列化的大小,只需使用QDataStream,从device()获取pos()之前,将对象输入数据流中并与之后的pos()进行比较。

此外,这一行显然是错误的:size+=sizeof(quint8*3)它不会给你三倍的字节大小。它将为您提供 int的大小 ,这就是乘法后结果的提升方式。

这里有一个漂亮的小类,你可以用它来完成任务:

class SerialSize {
public:
  SerialSize() : stream(&data) { data.open(QIODevice::WriteOnly); }
  template <typename T>
  quint64 operator ()(const T & t) {
    data.seek(0);
    stream << t;
    return data.pos();
  }
private:
  QBuffer data;
  QDataStream stream;
};

然后使用它:

  SerialSize size;
  qDebug() << size(QString("a")); // 6
  qDebug() << size(QString("aa")); // 8

在 sizeOf 函数的实现中,你应该尝试将size+=sizeof(quint8*3)更改为 size+=sizeof(quint8) * 3