IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Discussion :

Sérialiser en surchargeant << et >>


Sujet :

Qt

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 126
    Points : 48
    Points
    48
    Par défaut Sérialiser en surchargeant << et >>
    Bonjour,

    Merci par avance pour le coup de main !

    Je dois serialiser des objets de la classe suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    #ifndef POINTS_H
    #define POINTS_H
     
    #include "group.h"
    #include <QVector>
    #include <QString>
    #include <string>
    #include <iostream>
     
    class Points {
     
    public:
        Points();
        ~Points();
     
    public:
        QVector<Group*> groups(void) const { return _groups; }
     
        bool addGroup(Group& group);
        bool addGroup(Group* groupPtr);
     
        QVector<QString> groupNames(void) const;
        void removeGroup(const QString name);
        int clear(void);
     
        void display(std::ostream& stream) const ;
     
    private:
        QVector<Group*> _groups;
    };
     
    std::ostream& operator <<(std::ostream& stream, Points const& points);
     
    QDataStream& operator<<(QDataStream& out, const Points& points);
    QDataStream& operator>>(QDataStream& in, Points& points);
     
    #endif // POINTS_H
    Pour cela je m y prends comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    #include "points.h"
     
    Points::Points(void)
    {
     
    }
     
    Points::~Points(){
        for(int i = 0; i < _groups.size(); i++){
            delete _groups[i];
            _groups[i] = NULL;
        }
    }
     
    bool Points::addGroup(Group& group){
        // we first check that no group with the same name exists
        for(int i = 0; i < _groups.size(); i++){
            if(!group.name().compare(_groups.at(i)->name()))
                return false;
        }
        _groups.push_back(&group);
        return true;
    }
     
    bool Points::addGroup(Group* groupPtr){
        for(int i = 0; i < _groups.size(); i++){
            if(!groupPtr->name().compare(_groups.at(i)->name()))
                return false;
        }
        _groups.push_back(groupPtr);
        return true;
    }
     
    QVector<QString> Points::groupNames(void) const{
        QVector<QString> _names;
        for(auto it = _groups.cbegin(); it != _groups.cend(); ++it)
            _names.push_back((*it)->name());
        return _names;
    }
     
    int Points::clear(void){
        int nGroups(_groups.size());
        for(int i = 0; i < nGroups; i++){
            delete _groups[i];
            _groups[i] = NULL;
        }
        _groups.clear();
        return nGroups;
    }
     
    void Points::display(std::ostream& stream) const {
        std::cout << "This list of points contains " << _groups.size() << " groups :" << std::endl;
        for(int i = 0; i < _groups.size(); i++)
            stream << "\t" << *_groups[i] << std::endl;
    }
     
    std::ostream& operator <<(std::ostream& stream, Points const& points){
        points.display(stream);
        return stream;
    }
     
    QDataStream& operator<<(QDataStream& out, const Points& points){
        out << qint32(points.groups().size());
        for(int i = 0; i < points.groups().size(); i++)
            out << *(points.groups().at(i));
        return out;
    }
     
    QDataStream& operator>>(QDataStream& in, Points& points){
        qint32 size;
        in >> size;
        for(int i = 0; i < size; i++){
            Group group;
            in >> group;
            points.addGroup(new Group(group));
        }
        return in;
    }
    Dans le main...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    Points points;
     
        Point jp("Joans point", 1.2, 2.4);
        Point map("MAs point", 0.4, 5.7);
        Point fp("fannys point", 6.0, 7.0);
        Point np("Joans point", 1.3, 1.4);
        Point leosp("leosp", 4.5, 2.6);
     
        Group group("first group");
     
        group.addPoint(&jp);
        group.addPoint(&map);
        group.addPoint(&leosp);
     
        group.addPoint(&np);
        group.addPoint("AnewPoint", 5.2, 4.2);
     
     
     
        //std::cout << group << std::endl;
     
        //to fix
        //group.removePoint("leosp");
     
     
        Group sGroup("Second group");
        sGroup.addPoint(&fp);
        sGroup.addPoint("michels point", 8.3, 10.0);
     
        points.addGroup(group);
        points.addGroup(sGroup);
     
        Group tGroup(sGroup);
        tGroup.setName("third group");
     
        Points p2;
        p2.addGroup(tGroup);
        p2.addGroup(group);
     
        QString filename = "test.txt";
        QFile file(filename);
     
        if(!file.open(QIODevice::WriteOnly))
        {
            qDebug() << "Could not open " << filename;
            return 0;
        }
     
        QDataStream out(&file);
        out.setVersion(QDataStream::Qt_5_1);
     
        out << points << p2;
        //out << group << sGroup << tGroup;
        //out << jp << map << leosp << fp << np;
        file.flush();
     
        file.close();
     
        if(!file.open(QIODevice::ReadOnly))
        {
            qDebug() << "Could not open " << filename;
            return 0;
        }
     
        QDataStream in(&file);
        in.setVersion(QDataStream::Qt_5_1);
        Points points1, points2;
        Point point, point2, point3, point4, point5;
        Group g1, g2, g3;
        //in >> g1 >> g2 >> g3;
        in >> points1 >> points2;
        //in >> point >> point2 >> point3 >> point4 >> point5;
        file.close();
     
     
        //std::cout << g1 << g2 << g3 ;// << p2;
        std::cout << points1 << points2;
    Ce qui est etonnant c'est que jarrive tres bien a serialiser mes objets "Point" et mes objets Group mais pour les objets Points jobtiens ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    This list of points contains 2 groups :
    	Group's name : first group
    This group contains the following points : 
    	third group (1.25613e-38, 0)
    	Second group (1.25608e-38, 0)
    	 (0.4, 5.7)
    Je devrais avoir des noms de points a la place de "third group" et "Second group" et les coordonnees sont fausses.

    Quelqu'un aurait-il une idee s'il vous plait...? (je precise que je serialise mon objet de la classe Points de la meme facon que mon objet de la classe Group car ce sont des QVector de pointeurs dans les deux cas mais pour une raison que jignore ca se passe tres bien avec les groupes et pas bien du tout avec les points...)

    Merci encore

  2. #2
    Membre averti
    Homme Profil pro
    Analyse système
    Inscrit en
    Novembre 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyse système
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 227
    Points : 311
    Points
    311
    Par défaut
    Peut-on voir le code de la classe group, car je n'ai pas vu le texte qui apparait dans ta sortie dans le code publié.
    Hors il semblerait que cela soit la classe Group qui affiche ces données non ?

  3. #3
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 487
    Points : 6 170
    Points
    6 170
    Par défaut
    Bonjour,

    (Ma réponse n'a rien à voir avec << et >>.)

    Il y a un problème dans la gestion de la mémoire de tes groupes.
    Dans ton main, quand tu utilises Points::addGroup, tu mets à chaque fois en argument un objet qui a été alloué dans la pile.
    Or, le destructeur de Points fait un delete des groupes qui ont été ajoutés. Il y a donc une double destruction.

    Il y a aussi un problème de performance.
    Ta classe Points possède un ensemble de groupes identifiés par leur noms.
    Tu utilises un QVector<Group*> pour lequel l'ajout d'un groupe a une complexité linéaire.
    Il serait plus adapté d'utiliser :
    • si la destruction des groupes n'est pas gérée par Points : un QHash<QString, Groupe*> ou QHash<QString, const Groupe*> ;
    • si la destruction des groupes est gérée parfois par Points mais pas toujours : un QHash<QString, QSharedPointer<Groupe> > ou QHash<QString, QSharedPointer<const Groupe> > ;
    • si la destruction des groupes est gérée uniquement par Points : un QSet<Groupe> (ou éventuellement QHash<QString, Groupe> si t'as la flemme de surcharger qHash() pour Groupe).

    Dans tous les cas, l'ajout d'un groupe aura une complexité constante.

  4. #4
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 126
    Points : 48
    Points
    48
    Par défaut
    Merci a tous les deux pour vos reponses. J'ai pu resoudre mon probleme en utilisant des pointeurs intelligents, j' ai donc pu le laisser desallouer comme il faut car comme l'un d'entre vous l'a dit j'avais un probleme de double destruction. A bientot !

    Pour ce qui est des map, j' y ai pense aussi mais je ne vais pas manipuler plus de quelques dizaines d'objets, je ne pense pas que ca fasse par consequent une grande difference mais merci beaucoup j'en prends bonne note.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Surcharge de fonction d'un edit dynamique
    Par Tartar Ukid dans le forum C++Builder
    Réponses: 4
    Dernier message: 13/10/2003, 11h56
  2. SGBD ou sérialisation
    Par tiboleo dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 07/10/2003, 16h18
  3. Réponses: 5
    Dernier message: 24/04/2003, 11h47
  4. Surcharger le message d'erreur après un OnException
    Par Tirlibibi dans le forum XMLRAD
    Réponses: 2
    Dernier message: 24/04/2003, 11h42
  5. Réponses: 8
    Dernier message: 20/11/2002, 11h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo