1
votes

How can I know the size of qt data types in bytes; including QString objects if these data types were written on some QFile. I have to implement sizeOf() function in the Student class as below; something like we sizeof(struct student) in C.

Student 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;
        }

I know that data can be read with QDataStream & operator>>(QDataStream &in, Student &f); but I want to know size also for some other cases.

This does not give me a valid size on file. It seems Qt adds some extra bits while serializing; possibly for endian-ness independency on different platforms. Actual size is always more than returned by sizeOf() function

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;
            }

I am using QFile, QDataStream api. Qt version 4.8 on Windows 8.

2

2 Answers

4
votes

The size which sizeof will give you does not reflect the actual size an object might have. For example, the sizeof a QString in a 32 bit build will always be 4 bites, regardless how long the actual string is.

This sizeof operator includes stuff that doesn't need to be serialized, like the object's vtable pointer, and does not account for the size of dynamically allocated resources for that object.

You can easily determine the serializable size, just use a QDataStream, from the device() get the pos() before, input the object in the data stream and compare with the pos() afterwards.

Also, this line is clearly wrong: size+=sizeof(quint8*3) it will not give you three times the size of a byte. It will give you the size of an int, which is how the result is promoted after the multiplication.

Here is a nifty little class you can use for the task:

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;
};

Then use it:

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

In the implementation of the sizeOf function, you should try changing size+=sizeof(quint8*3) to size+=sizeof(quint8) * 3.