PDA

View Full Version : Serializing my Qt class with QDataStream



maro
30th October 2019, 20:40
Hello, i am working on my Quizproject but recently i stumbled upon a problem.I need to serialize my Qt class.I found this example on the internet https://stackoverflow.com/questions/2570679/serialization-with-qt, it's the first answer.I want to implement it on a similar way on my class here's my class:

class Answer{
private:
qint8 id;
QString answer;

public:
Answer(QString nAnswer, qint8 nId);
QString getAnswer();
qint8 getId();

};

class Card
{
private:
QString question;
QVector<Answer> answers;
qint8 solutionId;

public:
Card(QString nQuestion, qint8 nSolutionId, QVector<Answer> nAnswers);
QString getQuestion();
QVector<Answer> getAnswers();
qint8 getSolutionId();

};

Answer::Answer(QString nAnswer, qint8 nId)
{
answer = nAnswer;
id = nId;
}


Card::Card(QString nQuestion, qint8 nSolutionId, QVector<Answer> nAnswers)
{
question = nQuestion;
solutionId = nSolutionId;
answers = nAnswers;
}

d_stranz
5th November 2019, 21:45
So what is the problem? The StackOverflow answer tells you exactly what you need to do: implement the >> and << operators for your classes:



QDataStream &operator<<(QDataStream &out, const Answer & answer);
QDataStream &operator>>(QDataStream &in, Answer & answer);

QDataStream &operator<<(QDataStream &out, const Card & card);
QDataStream &operator>>(QDataStream &in, Card & card);


The only tricky part is how to serialize the QVector<Answer> members. The usual way is to first serialize the count (number of members in the vector), then serialize each member.



QDataStream & operator<<( QDataSream & out, const Card & card )
{
int nAnswers = card.getAnswers.size();
out << nAnswers;
foreach( answer, card.getAnswers() )
out << answer; // assumes you have implemented operator<< for the Answer class

// do other Card data elements

return out;
}


You might find it convenient to add set...() methods to your classes (Card::setAnswers( const QVector< Answer > & answers ), etc.) because the way you have defined Card and Answer, the only way you can set these fields is in the constructor - there is no way to set them independently, for a Card or Answer instance that already exists.

You should also use references to pass or return by reference instead of by value:


const QVector< Answer > & Card::getAnswers() const;


The way you have implemented it, this methods makes a complete copy of the QVector before returning it. Using a reference means that no copying is done.