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 :

Acces à une meth avec un it d'un conteneur de ptr sur objet


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Juillet 2018
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2018
    Messages : 27
    Points : 27
    Points
    27
    Par défaut Acces à une meth avec un it d'un conteneur de ptr sur objet
    Bonjour la comunauté,

    DSL pour le style télégraphique du titre, je n'ai pas trouvé plus explicite...

    J'ai un vector qui contient des pointeurs std::unique_ptr pointant sur des objets de la classe Fenetre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector <std::unique_ptr<Fenetre> > vPfenetre
    Je voudrais accéder à la methode getType() de la classe Fenetre qui me renvoie un typeFenetre (enum class Public déclaré dans la classe Fenetre)

    Si je code comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    for(unsigned int i(0); i < m_vPfenetre.size(); ++i)
                {
                    if(vPfenetre[i] -> getType() == Fenetre::typeFenetre::fCarte)
                    {
                        // fait des trucs
                        i = vPfenetre.size();
                    }
                }
    ça compile et fonctionne comme espéré.

    mais si je code avec un itérator comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
       for(auto it = vPfenetre.begin(); it != vPfenetre.end(); ++it)
                {
                    if (*it -> getType() == Fenetre::typeFenetre::fCarte) // it ou *it renvoie le même message d'erreur
                    {
                    // fait des trucs
                    it = vPfenetre.end();
                    }
                }
    Le compilateur me dit :
    error: 'class std::unique_ptr<Fenetre>' has no member named 'getType'

    Je ne comprends pas : *it ne déréférence t-il pas le pointeur itéré de vPfenetre qui accéde à la méthode getType() de la classe Fenetre via l'opérateur -> comme vPfenetre[i] dans le premier cas ?
    J'ai potentiellement quelques cas similaires et j'aimerais bien comprendre l'utilisation des itérators avant de travailler ces autres cas.

    Rick.

  2. #2
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    -> est prioritaire sur *, il faut ajouter des parenthèses: (*it)->getType().

  3. #3
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,

    Et attention à ta ligne 6. si tu mets end() dans it, le ++it qui suit te fait aller au dela de end() qui n'a aucun sens! Un simple break est largement préférable!
    Il y a plus simple pour parcourir une collection :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
                for ( auto&& pfen : vPfenetre )
                {
                    if ( pfen->getType() == Fenetre::typeFenetre::fCarte )
                    {
                    // fait des trucs
                    break;
                    }
                }

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Juillet 2018
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2018
    Messages : 27
    Points : 27
    Points
    27
    Par défaut
    Ha ha c'était aussi simple que ça !

    DSL du dérangement mais la syntaxe du c++ est tellement pointue que je n'ai pas encore les bons réflexes de contrôle (comme vérifier systématiquement les règles de priorité par ex...)
    @Dalfab : Noté, merci du tuyau. (les && ne sont pas encore de ma compétence de faux débutant, mais le break oui ! ^^)

    Sujet clos.
    Rick.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Ceci étant dit, tout indique dans ta question que ta classe Fenetre sert de classe à toute une hiérarchie qui va bien au delà de la seule classe dont le type est représenté par fCarte, et, par conséquent, que tu utilise la fonction getType pour assurer une certaine forme de RTTI (Run Time Type Information).

    Je ne serais, du coup, pas plus étonné que cela si la partie de ton code que tu as désignée à l'aide du commentaire // fait des trucs commençait par un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FenetreCarte * temp = static_cast<FenetreCarte *>( (it*)get() );
    ou quelque chose de très similaire (le nom de la classe peut changer, tu utilises peut-être dynamic_cast, ou pire, un cast barbare "à la C" ).

    Et je ne serais pas étonné outre mesure si ton code se poursuivait avec une série de else if ( pfen->getType() == une valeur différente) dont tous les cas seraient basés sur une logique sommes toutes similaires.

    Ce genre de pratique est une véritable catastrophe!!! parce qu'elle va totalement à l'encontre du deuxième principe SOLID : le O, pour OCP, qui est l'acronype de Open Closed Principle (ou si tu préfère en francais, le "principe Ouvert / Fermé"), qui nous rappelle qu'un code doit être "ouvert aux évolutions", mais "fermé aux modifications".

    Pour t'aider à la compréhension de ce principe, disons simplement que, tu as écrit ton code, qu'il compile, et que tu as pu déterminer qu'il fait exactement ce qu'il est sensé faire, tu n'as plus la moindre raison d'aller le modifier : l'ajout d'une évolution ou d'une nouvelle fonctionnalité doit pouvoir se faire sans toucher à la moindre ligne du code existant.

    La logique que je subodore au travers du peu de code que tu donnes me laisse à penser -- même si je peux me tromper, ce dont je doute -- me laisse à penser que, si tu voulais ajouter un nouveau type de fenêtre demain, tu serais obligé d'aller modifier cette succession de if ... else if pour pouvoir prendre le nouveau type de fenêtre en compte.

    Pire encore : je suis quasiment sur que, au fil du temps, tu vas te retrouver avec des dizaines de places dans ton code où ce genre de logique sera mise en œuvre. Et c'est bien là que se trouve tout le problème, car cela signifie que tu devras modifier ton code à des dizaines d'endroits pour pouvoir prendre le nouveau type de fenêtre en compte.

    Or, au fil du temps, tu vas forcément oublier la plupart de ces endroits dans ton code, pour la simple et bonne raison que tu sera concentré sur "autre chose". Et le résultat ne se fera pas attendre : il y aura systématiquement "toute une série" de situations dans lesquelles ... ton nouveau type de fenêtre ne sera pas pris en compte; c'est à dire autant de situations dans lesquelles tu sera face à un bug

    Pour éviter ce genre de problème, le concept clé est double dispatch, dont l'une des mises en oeuvre classique (bien que n'étant pas forcément la plus efficace dans toutes les situations) est représentée par le patron de conception Visiteur.

    Je ne peux que te recommander avec la plus grande vigueur de t'intéresser au plus vite à ce concept et à sa mise en oeuvre
    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

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

Discussions similaires

  1. Module de vérification d'accès à une page avec code unique
    Par avinain dans le forum Général Conception Web
    Réponses: 2
    Dernier message: 02/08/2011, 12h28
  2. Eviter l'accès à une page avec le bouton back
    Par friedamichelle dans le forum JSF
    Réponses: 2
    Dernier message: 10/02/2011, 11h39
  3. Accès à une page avec mot de passe
    Par aca1024 dans le forum Sécurité
    Réponses: 4
    Dernier message: 09/06/2009, 23h50
  4. Réponses: 2
    Dernier message: 07/10/2008, 14h11

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