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

 C++ Discussion :

Instancier une classe à partir d'une variable


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Par défaut Instancier une classe à partir d'une variable
    Bonjour à tous.

    Me voici confronté à un problème qui à du être posé plusieurs fois mais dont je ne trouve pas la solution. Veuillez m'excuser par avance de ce doublon.

    Je souhaite instancier de façon statique ma classe NavaidsPoint :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
        NavaidsPoint(QString code, double latitude, double longitude, QString country = "") 
        {
            m_code = code;
            m_latitude = latitude;
            m_longitude = longitude;
            m_country = country;
            m_position.setLatitude(latitude);
            m_position.setLongitude(longitude);
     
        }
    avec la variable str de ma fonction addNavaids :
    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
     
    void addNavaids(){
        QFile file(QCoreApplication::applicationDirPath() + "/data/Waypoints.txt");
        if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            QMessageBox::information(0, "erreur lecture fichier : " + file.fileName(), file.errorString());
            return;
        }
        //Parser du fichier Waypoints
        QTextStream in(&file);
        while(!in.atEnd()) {
            QString line = in.readLine();
            QStringList fields = line.split(",");
            QString str = fields.at(1);
            double latitude = str.toDouble();
            str = fields.at(2);
            double longitude = str.toDouble();
            str = fields.at(0);
     
            NavaidsPoint str(str,latitude, longitude);
        }
        return;
    }
    A la compilation, je reçois l'erreur suivante : "conflicting declaration 'NavaidsPoint str' - NavaidsPoint str(str,latitude, longitude);"

    Je ne comprends pas mon erreur. Que dois-je corriger ?

    Merci pour votre aide.

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    NavaidsPoint str(str,latitude, longitude);
    Tu ne peux pas créer un NavaidsPoint nommé str, puisque tu as déjà une variable de ce nom (en l'occurence une QString).

    Je parie que la ligne d'erreur suivante est "previous declaration here: "

    essaye plutot:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    NavaidsPoint point(str,latitude, longitude);

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Par défaut
    Oui, tu as raison, la ligne d'erreur suivante est bien : previous declaration as 'QString str'.

    Mais je ne veux pas appeler mon instance str, mais la valeur que vaut str à chaque boucle ( mettons d'abord Oslo, puis Paris, puis Berlin...).

    C'est ça qui ne fonctionne pas...

  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Ce qui ne va pas, c'est que ta variable NavaidsPoint a le même nom qu'une autre définie dans le même bloc.
    Change le nom de l'une des deux.

    Ton NavaidsPoint n'est probablement pas une string, nomme-le plus explicitement (point, current, current_point, somme_cool_place...)

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 489
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 489
    Par défaut
    Si le but, c'est de créer des objets depuis un fichier, cela s'appelle de la désérialisation.
    Et des framework de sérialisation/désérialisation, c'est pas ça qui manque.
    Cela éviterait de réinventer une usine à gaz.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Par défaut
    voici la partie de code modifiée pour instancier mon NavaidsPoint :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
            str = fields.at(0);
     
            QString currentPoint = str;
     
            NavaidsPoint currentPoint(str, latitude, longitude);
        }
        return;
    }
    J'obtiens exactement le même message d'erreur. La valeur de currentPoint n'est pas utilisée. Le système utilise le "mot" currentPoint au lieu de le lire comme une variable et d'en extraire la valeur. Et bien sûr, il dit qu'il est déjà défini. Ce n'est pas possible qu'on ne puisse pas instancier une classe à partir d'une variable, je ne dois pas être le seul être humain sur terre à avoir voulu faire cela...

    Quant à la sérialisation/désérialisation, je pense que ce concept n'est pas relatif à ce que je veux faire.
    Le fichier waypoints.txt est simplement composé de ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    ...
    ESPEG,30.96778,106.00889,ZP
    ESPEG,-33.82835,122.01582,YM
    ESPEH,-33.66709,121.77498,YM
    ESPEI,-33.74488,122.01744,YM
    ESPEM,-33.68509,121.83089,YM
    ESPER,-27.01139,-63.63222,SA
    ESPIG,43.51072,4.10519,LF
    ESPIN,40.84944,-2.50000,LE
    ESPIN,-20.93000,-54.91467,SB
    ...
    c'est assez simple en fait. Je veux que mon objet NavaidsPoint soit instancié avec le code à 5 lettres de la première colonne, pas plus.

    J'en oublierai presque de vous remercier pour votre aide.


  7. #7
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 489
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 489
    Par défaut
    Quant à la sérialisation/désérialisation, je pense que ce concept n'est pas relatif à ce que je veux faire.
    Vous vous leurrez, c'est parfaitement ce que vous tentez de faire, de manière très maladroite.

    Bon vu la "complexité" du bidule, pas besoin de sortir le croiseur interstellaire pour ça.

    Vous faites une méthode qui prend en entré un stream du fichier.
    Il lit ligne à ligne le stream en mettant la ligne courante dans une std::string.
    Vous utilisez une expression régulière pour valider et découper votre ligne.
    Un truc de la forme "([A-Z]{5}),(-?\d+(?:\.d+)),(-?\d+(?:\.d+)),([A-Z]{2})"
    Vous avez en sortie, les chaines découpés, et vous utilisez "std::stod" pour récupérer les doubles depuis les captures 2 et 3.
    Vous n'aurez ensuite qu'à utiliser le constructeur qui va bien avec ces 4 arguments tout chaud.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Par défaut
    Merci bacelar, mais je ne vois pas beaucoup de différence entre ce que vous me proposez et le second code qui est affiché dans mon premier post.

    Ici, mon problème n'est pas de passer les attributs à la classe - effectivement, je les ai tous -, c'est de donner un nom différent pour chaque instance.

    Maintenant, faut-il que je donne un nom d'instance différent à chacune d'entre elle ? Il me semble bien que, si l'on a une classe personnage, et que l'on désire deux instances, on va appeler la première Dupont et la seconde Durand, par exemple, pas tous les deux Persos.

    D'où ma recherche actuelle de nommer mes instances à partir du code du point géographique considéré.

  9. #9
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 489
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 489
    Par défaut
    mais je ne vois pas beaucoup de différence entre ce que vous me proposez et le second code qui est affiché dans mon premier post.
    Votre code ne valide pas apriori les données.
    A la moindre erreur de format, c'est la cata.
    Et avec l'habitude, une expression régulière exprime explicitement un format.
    Pour changer de format, vous changez l'expression régulière et vous n'avez pas besoin de changer au code dans la très grande majorité des cas.
    etc...

    Après, il n'est pas obligatoire d'avoir un "nom" pour chaque objet crée.
    Un index dans un "std::vector<NavaidsPoint>" fait l'affaire.
    Si vous devez faire des recherches par nom, une "std::map<std::string,NavaidsPoint>" fera aussi bien l'affaire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
        QTextStream in(&file);
        std::vector<NavaidsPoint> vec;
        while(!in.atEnd()) {
            QString line = in.readLine();
            QStringList fields = line.split(",");
            QString str = fields.at(1);
            double latitude = str.toDouble();
            str = fields.at(2);
            double longitude = str.toDouble();
            str = fields.at(0);
     
            vec.pushback( NavaidsPoint(str,latitude, longitude));
        }

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par KonTiKI Voir le message
    Maintenant, faut-il que je donne un nom d'instance différent à chacune d'entre elle ?
    Bien sur que oui.
    Une fois compilée, les noms de variables n'existent plus. Une variable c'est juste un moyen d'accéder à la mémoire réservée par un moyen plus simple que son adresse, ça n'existe pas dans le programme final.
    Citation Envoyé par KonTiKI Voir le message
    Il me semble bien que, si l'on a une classe personnage, et que l'on désire deux instances, on va appeler la première Dupont et la seconde Durand, par exemple, pas tous les deux Persos.
    Tu veux 3 villes ? Tu crées 3 variables avec 3 noms différents. Sinon le compilateur te le rappellera avec une erreur souvent bien explicite.
    Tu veux une collection de villes ? Tu utilises une collection vector ou map qui permet d'utiliser un nom plus clair en clé.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  11. #11
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,
    Citation Envoyé par KonTiKI Voir le message
    J'obtiens exactement le même message d'erreur. La valeur de currentPoint n'est pas utilisée. Le système utilise le "mot" currentPoint au lieu de le lire comme une variable et d'en extraire la valeur. Et bien sûr, il dit qu'il est déjà défini. Ce n'est pas possible qu'on ne puisse pas instancier une classe à partir d'une variable, je ne dois pas être le seul être humain sur terre à avoir voulu faire cela...
    Ben oui, mais tu as une ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QString currentPoint = str;
    qui déclare une variable de type QString, dont le nom est currentPoint et qui prend la même valeur que str (qui existe par ailleurs). Elle ne sert à rien ici!

    Puis, à la ligne suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    NavaidsPoint currentPoint(str, latitude, longitude);
    tu déclares une variable qui s'appelle... currentPoint (tiens, c'est le même nom!!! ) mais qui est de type NavaidsPoint et qui sera construit en prenant str, latitude et longitude comme paramètre...

    Cherchez l'erreur! C++ est un langage fortement typé: une fois que l'on a déclaré qu'une variable était d'un type particulier, on ne peut plus changer le type de cette variable. Si l'on a besoin d'une variable d'un autre type, il faudra lui donner un nom différent de la première

    Il faut apprendre à lire et à comprendre les messages que le compilateur t'envoie, car ce n'est pas ton ennemi! Bien au contraire, c'est ton meilleur ami, qui fait tout ce qu'il peut pour s'assurer que le code que tu écrit soit correct, pour t'aider à trouver les endroits où il y a un problème, pour pour t'aider à déterminer l'origine du problème.

    Il faut juste arriver à comprendre ce qu'il dit. Et respecter les règles imposées par le langage.

    Tu viens sans doute de langages plus "permissifs" avec lesquels tu pouvais changer le type d'une variable à la volée, en décidant par exemple que maVar était une chaine de caractères au début d'une fonction, mais en décidant au milieu de la fonction que maVar devenait un entier. Tu ne peux pas faire cela en C++.

    Une fois que tu auras compris cela, tu t'évitera bien des soucis
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Par défaut
    Merci messieurs, c'est un grand plaisir de poster sur ce forum, vos réponses étant toujours pour moi un grand pas en avant, même s'il me faut travailler durement avant de comprendre certaines de vos réponses.

    Pour préciser, j'avais bien compris que le nom de variable ne pouvait être utilisé de nouveau sous un autre type. D'ailleurs par principe, je ne fais jamais cela. Non, mon problème était bien d'appréhender une solution comme celle que vous avez fini par me donner avec le concept de collection qui est la bonne réponse à ma question certainement mal posée.

    J'ai donc modifié mon code de la sorte :

    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
     
    void addNavaids(){
        QFile file(QCoreApplication::applicationDirPath() + "/data/Waypoints.txt");
        if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            qDebug() << "erreur lecture fichier : " + file.fileName() << file.errorString();
            return;
        }
        //Parser du fichier Waypoints
        QTextStream in(&file);
        QVector<NavaidsPoint> Vec;
        while(!in.atEnd()) {
            QString line = in.readLine();
            QStringList fields = line.split(",");
            QString str = fields.at(1);
            double latitude = str.toDouble();
            str = fields.at(2);
            double longitude = str.toDouble();
            str = fields.at(0);
            QString country = fields.at(3);
     
            Vec.push_back( NavaidsPoint(str, latitude, longitude, country));
        }
    }
    J'intègrerai, bien sûr, la validation du format telle que précisée par bacelar - que je remercie tout particulièrement au passage - n'ayant pas compris cette subtilité par moi-même.

    Maintenant, avec ce nouveau code, je rencontre le problème suivant :
    NavaidsPoint::NavaidsPoint(const NavaidsPoint&)' is implicitly deleted because the default definition would be ill-formed:

    voici le prototype de ma classe NavaidsPoint :
    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
     
    class NavaidsPoint: public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QGeoCoordinate position READ position WRITE setPosition NOTIFY positionChanged)
     
    public:
        NavaidsPoint(QString code, double latitude, double longitude, QString country = "");
        void setPosition(const QGeoCoordinate &c);
        QGeoCoordinate position() const;
        Q_INVOKABLE QString oaciCode() const;
        Q_INVOKABLE QString countryCode() const;
     
    signals:
        void positionChanged();
     
    private:
        QGeoCoordinate m_position;
        double m_latitude;
        double m_longitude;
        double m_altitude;
        QString m_code;
        QString m_country;
    };
    Mes recherches sur le net ne m'ont pas permis de le résoudre, sauriez-vous identifier la cause de ce problème de compilation ?

    Merci encore pour votre aide.

  13. #13
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 489
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 489
    Par défaut
    Je pense qu'il manque un constructeur par copie dans la classe NavaidsPoint.

  14. #14
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Perso j'en pense surtout qu'hériter de QObject n'est en rien une bonne idée. On est clairement en présence d'un objet "métier".
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  15. #15
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    De toute évidence (ca fait un bail que je n'ai plus été voir du coté du fichier d'en-tête dans lequel est définie la classe QObject), le constructeur de copie de la classe QObject, et, dés lors, par la même occasion sans doute l'opérateur d'affectation, ont été désactivés, ce qui est "logique" pour une classe ayant sémantique d'entité, comme le sera toute classe destinée à servir de classe de base dans une hiérarchie de classe.

    Le truc, c'est que, avec le constructeur de copie et l'opérateur d'affectation désactivé, tu ne peux plus écrire un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    MaClasse::MaClasse(Type1 param1, Type2 param2){
        /* soient le constructeur de copie et l'opérateur d'affectation
         * marqués delete pour la classe ClasseMembre
         * et m_membre est une donnée membre de type ClasseMembre
         */
       m_membre = ClasseMembre(param1, param2);
    }
    car cela crée une variable temporaire anonyme qui sera utilisée (par le constructeur de copie) pour initialiser la donnée m_membre.

    Il y a deux possibilités pour résoudre ce problème:

    La première (et celle qui devrait être préférée) est d'utiliser les listes d'initialisation, et d'avoir donc (pour autant que faire se peut) un code qui serait proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    MaClasse::MaClasse(Type1 param1, Type2 param2):  m_membre{param1, param2}{
        /* soient le constructeur de copie et l'opérateur d'affectation
         * marqués delete pour la classe ClasseMembre
         * et m_membre est une donnée membre de type ClasseMembre
         */
    }
    qui fonctionnent à tous les coups, et qui sont d'ailleurs le seul moyen d'initialiser certaines données membres (lorsqu'elles prennent la forme d'une référence, par exemple).

    Une autre solution (qu'il vaut mieux éviter autant que possible) est d'avoir recours à l'utilisation de pointeurs et à l'allocation dynamique de la mémoire, sous une forme qui pourrait ressembler à quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /*le membre de la classe sera défini sous la forme de */
    ClasseMembre * m_membre{nullptr};
     
    MaClasse::MaClasse(Type1 param1, Type2 param2){
        /* soient le constructeur de copie et l'opérateur d'affectation
         * marqués delete pour la classe ClasseMembre
         * et m_membre est une donnée membre de type ClasseMembre
         */
       m_membre = new ClasseMembre(param1, param2);
    }
    (comme nous sommes sous Qt, et que la classe QObjet a un système de parent / enfants correct, on va passer le speach sur les pointeurs intelligents )
    [/CODE]
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Perso j'en pense surtout qu'hériter de QObject n'est en rien une bonne idée. On est clairement en présence d'un objet "métier".
    Je ne peux discuter de ce point mais, l'exemple QT sur lequel je me base (plane spotter) précise ceci :

    The main purpose of the PlaneController class is to track the current coordinates of the plane at a given time. It exposes the position via its position property.

    class PlaneController: public QObject
    {
    Q_OBJECT
    Q_PROPERTY(QGeoCoordinate position READ position WRITE setPosition NOTIFY positionChanged)
    // ...
    };
    Je suis donc parti de cette base, d'autant que la macro Q_PROPERTY l'impose : "This macro is used for declaring properties in classes that inherit QObject." Et cette déclaration est impérative pour que QML puisse fonctionner avec les données traitées par le code C++.

    La première (et celle qui devrait être préférée) est d'utiliser les listes d'initialisation
    J'ai redéfini mon constructeur de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    NavaidsPoint::NavaidsPoint(QString code, double latitude, double longitude, QString country):
        m_code(code), m_latitude(latitude), m_longitude(longitude), m_country(country)
    {
        m_position.setLatitude(latitude);
        m_position.setLongitude(longitude);
    }
    J'aurais du dès le départ utiliser une liste d'initialisation car de façon générale, c'est mieux. Il me reste à comprendre ceci : "m_membre est une donnée membre de type ClasseMembre". Cette modification de mon code ne supprime pas l'erreur.

    Je pense qu'il manque un constructeur par copie dans la classe NavaidsPoint.
    Oui clairement. Je l'ai rajouté ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    NavaidsPoint::NavaidsPoint(NavaidsPoint const& autre):
        m_code(autre.code), m_latitude(autre.latitude), m_longitude(autre.longitude), m_country(autre.country)
    {
        m_position.setLatitude(autre.latitude);
        m_position.setLongitude(autre.longitude);
    }
    Là l'erreur disparaît.

    en revanche , il en reste une relative à l'instanciation par le Qvector :
    C:\Qt59\5.9.2\mingw53_32\include\QtCore\qvector.h:321: erreur : no matching function for call to 'NavaidsPoint::NavaidsPoint()'
    new (from++) T();
    ^

    plus détaillée ici :
    In file included from C:\Qt59\5.9.2\mingw53_32\include\QtCore/qdebug.h:51:0,
    from C:\Qt59\5.9.2\mingw53_32\include\QtCore/QDebug:1,
    from ..\TestGeoCppQml\main.cpp:7:
    C:\Qt59\5.9.2\mingw53_32\include/QtCore/qvector.h: In instantiation of 'void QVector<T>::defaultConstruct(T*, T*) [with T = NavaidsPoint]':
    C:\Qt59\5.9.2\mingw53_32\include/QtCore/qvector.h:579:41: required from 'void QVector<T>::reallocData(int, int, QArrayData::AllocationOptions) [with T = NavaidsPoint; QArrayData::AllocationOptions = QFlags<QArrayData::AllocationOption>]'
    C:\Qt59\5.9.2\mingw53_32\include/QtCore/qvector.h:676:20: required from 'void QVector<T>::append(T&&) [with T = NavaidsPoint]'
    C:\Qt59\5.9.2\mingw53_32\include/QtCore/qvector.h:260:35: required from 'void QVector<T>::push_back(T&&) [with T = NavaidsPoint]'
    ..\TestGeoCppQml\main.cpp:38:71: required from here
    C:\Qt59\5.9.2\mingw53_32\include/QtCore/qvector.h:321:13: error: no matching function for call to 'NavaidsPoint::NavaidsPoint()'
    new (from++) T();
    ^
    In file included from ..\TestGeoCppQml\main.cpp:12:0:
    ..\TestGeoCppQml\navaidspoint.h:16:5: note: candidate: NavaidsPoint::NavaidsPoint(const NavaidsPoint&)
    NavaidsPoint(NavaidsPoint const& autre); //Constructeur de copie
    ^
    ..\TestGeoCppQml\navaidspoint.h:16:5: note: candidate expects 1 argument, 0 provided
    ..\TestGeoCppQml\navaidspoint.h:15:5: note: candidate: NavaidsPoint::NavaidsPoint(QString, double, double, QString)
    NavaidsPoint(QString code, double latitude, double longitude, QString country = "");
    ^
    ..\TestGeoCppQml\navaidspoint.h:15:5: note: candidate expects 4 arguments, 0 provided
    Je ne souhaite pas être trop... lourd, mais si vous entrevoyez une possibilité de correction, je reste preneur.

    Merci encore.

  17. #17
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par KonTiKI Voir le message
    Je ne peux discuter de ce point mais, l'exemple QT sur lequel je me base (plane spotter) précise ceci :
    Lire un exemple/tuto c'est bien, le comprendre c'est mieux.
    Ton truc NavAids c'est pas juste des coordonnées ? Pourquoi les coordonnées devraient avoir connaissance de Qt ?
    Que tu aies un truc autour pour le manipuler qui soit Qt parce qu'il s'agit du programme, oui, qu'il en soit une part entière, non.
    Ton truc c'est limite un POD avec les coordonnées qui t'intéressent.
    Et en lisant juste l'exemple je vois qu'il s'agit du PlaneController et pas des coordonnées elles-mêmes. Ton objet c'est la position property et pas le contrôleur qui track the current coordinates.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  18. #18
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Par défaut
    Bousk, ce n'est pas facile d'argumenter quand on comprend juste le vernis des choses et qu'on ne peut plonger au cœur, ce qui est mon cas. Ce que j'essaie de faire c'est simplement d'afficher des points au bon emplacement sur un fond de carte osm. D'ailleurs si tu pouvais me donner la signification de POD .

    Alors oui, j'essaye d'utiliser QT comme environnement, car ce que j'y vois s'approche de ce que je souhaite faire.

    Il me semble que pour que les données de position du point extraites par la portion de code en C++ soient utilisées par QML pour l'affichage, elles doivent dériver de la classe QObject.

    Lorsque je lis la doc qt au chapitre Integrating QML and C++, il est clairement spécifié ceci : "To provide some C++ data or functionality to QML, it must be made available from a QObject-derived class. "

    Alors, oui, j'ai (beaucoup) lu, je n'ai peut-être pas compris, mais j'ai cru comprendre. Et comme les exemples d'intégration C++/QML sont rares, je me suis basé sur celui qui s'approchait le mieux de ce que je voulais faire.

    Par ailleurs, mon code fonctionne correctement. Si je tape mes valeurs en dur, j'obtiens exactement ce que je souhaite.

    Bien sûr cette réponse n'est pas vindicative, je tente simplement - et humblement - d'expliquer les raisons qui m'ont amener à structurer mon code de cette façon. C'est peut-être maladroit et à coté de la plaque, mais c'est ce que j'ai cru comprendre qu'il fallait faire à partir de mes observations.

  19. #19
    Membre Expert
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Par défaut
    Une petite remarque en passant qui pourra peut-être t'éviter une situation gênante à l'avenir : NavAids* n'est peut-être pas le meilleur nom pour tes classes. AIDS est l'acronyme anglo-saxon pour le syndrome d'immunodéficience acquise (SIDA).

    Une meilleur nom pourrait-être NavAid, aid étant en anglais un assistant.

  20. #20
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    allons plus loin navaid::Point serait encore mieux, c'est à dire, une struct ou class Point (ou point) dans le namespace navaid.

Discussions similaires

  1. Réponses: 3
    Dernier message: 24/03/2011, 15h58
  2. accéder à variable privée d'une classe à partir d'une autre classe
    Par restapa dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 05/08/2010, 08h56
  3. modifier une variable d'une classe à partir d'une autre classe
    Par Rniamo dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 16/03/2008, 20h40
  4. Réponses: 2
    Dernier message: 29/03/2007, 14h08
  5. Accéder à des objets d'une Form à partir d'une classe
    Par kinouseb dans le forum Windows Forms
    Réponses: 4
    Dernier message: 23/01/2007, 18h07

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