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

Calculate serialization size of objects in Qt

我如何知道 qt 数据类型的大小(以字节为单位);如果这些数据类型写在某些 QFile 上,则包括 QString 对象。我必须在 Student class 中实现 sizeOf() 函数,如下所示;就像我们 sizeof(struct student) 在 C.

学生class

        #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函数的实现中,你应该 尝试将 size+=sizeof(quint8*3) 更改为 size+=sizeof(quint8) * 3.

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

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

可以很容易的确定serializable的大小,只需要用一个QDataStream,从device()得到pos()之前,在数据流中输入对象并与pos()之后。

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

这里有一个漂亮的小 class 可以用于任务:

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