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

SL & STL C++ Discussion :

[std::map] encapsulation difficile


Sujet :

SL & STL C++

  1. #1
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut [std::map] encapsulation difficile
    Bonjour à tous,
    Je suis en train de faire évoluer la structure d'un ancien programme. Pour des raisons pratiques, je remplace mon std::vector<int, int> par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::map <int, Point> tableau_points_;
    Pour faire simple:
    • un tableau_points est associé à une image
    • chaque Point doit avoir un "marqueur" (clé) fixe, car un autre Point lui est associé dans une autre image, qui possédera lui-même le même marqueur.


    Comment faire pour donner une bonne encapsulation à cette map?

    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
    class PointDeControle
    {
    	typedef Point<int> Point;
     
    public:
    	PointDeControle();
     
    	void ajouterPoint(Point & point);
    	void supprimerPoint(Point &);
     
    	int getSize(void) { return tableau_points_.count() }
    	std::pair<int, Point> getPoint( int numero_point); // Comment faire mieux???
    	int getCle(Point & point);
     
    private:
    	std::map <int, Point> tableau_points_;
    	std::vector <int> cle_supprime_; // sauvegarde des clés supprimées pour les réinsérer ensuite
    };
    Mise en évidence du problème du client:
    1. Ajout de 10 points par clé croissante (1,2,3,4,5,6,7,8,9,10).
    2. Suppression des points 4 et 5
    3. getPoint() ???? Comment savoir quelle clé est valide?



    La fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::pair<int, Point> getPoint( int numero_point)
    permet au client de boucler sur tous les points:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for (int i = 0; i < point.getSize(); i++) 
    {
          getPoint(i); // on récupère le point
    }
    Ce code vous parait-il pourri? bien?
    Vaut-mieux fournir un itérateur au client?

    Merci pour votre aide précieuse !

  2. #2
    Membre éclairé Avatar de ZaaN
    Inscrit en
    Novembre 2005
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 819
    Par défaut
    Citation Envoyé par poukill
    Vaut-mieux fournir un itérateur au client?
    certainement a condition que l'ordre du conteneur soit respecté...

  3. #3
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par ZaaN
    certainement a condition que l'ordre du conteneur soit respecté...
    C'est pas "dangereux" de fournir un itérateur?

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Citation Envoyé par poukill
    C'est pas "dangereux" de fournir un itérateur?
    Dans ton cas tu peux ne renvoyer que des itérateurs constants.
    A quel genre de dangers pensais-tu ?

  5. #5
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Je sais pas trop de quoi je voulais parler en fait.
    Par exemple, je fourni un itérateur, et entre temps le client supprime des éléments de la map (qui est une liste chainée) via des fonctions membres bien valides...
    L'itérateur va t-il se planter? Le client risque t-il d'accéder à des données non ou plus allouées? Je ne pense pas, mais je ne saurai répondre à cette question...

    J'ai trouve 2 solutions à mon problème d'accès de map:
    1. Je fourni un itérateur constant pour parcourir ma map. C'est bien, mais ça donne pas mal de boulot encore au "client".
    2. Je surcharge l'opérateur [] pour accéder aux données. Ainsi , le client aurait juste à faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    for (int i = 0; i < tableau.getSize(); i++) {
              ... = tableau[i];
    }
    Qu'en pensez-vous? Quelle est la "meilleure" solution?

  6. #6
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Parmi les deux solutions:
    1) Renvoyer une paire d'itérateurs (ou deux itérateurs) : un sur begin(), un sur end().
    2) Surcharger l'opérateur [] pour accéder à la map

    Laquelle me conseilleriez vous?

    Merci!

  7. #7
    Membre éclairé Avatar de ZaaN
    Inscrit en
    Novembre 2005
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 819
    Par défaut
    La deuxième !

  8. #8
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par ZaaN
    La deuxième !
    Merci ZaaN pour ta réponse!
    J'attend éventuellement d'autres avis avant de mettre !!!

    A vous les studios !

  9. #9
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par ZaaN
    La deuxième !
    Finalement, pour accéder au n-ième élément, il va falloir que je crée un const_iterator pour allez le chercher et finalement le renvoyer.

    Le client utilisant l'opérateur [], s'il veut parcourir toute la map, va faire un genre de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for (int i = 0; i< tableau_map.size(); i++)
         temp = tableau_map[i];
    Finalement, il y a beaucoup de perte de temps...

    L'itérateur est une solution moins jolie, mais plus rapide AMHA.

    J'attend vos remarques

  10. #10
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Disons que l'opérateur [] sera utile si l'on veut accéder à un élement aléatoirement. Mais pour un parcours purement séquentiel, c'est clair que les itérateurs sont un meilleur choix.

  11. #11
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Tout à fait d'accord avec toi Laurent...

    Une dernière question :

    1) Si on fourni un itérateur, et qu'entre temps on supprime des éléments du conteneur... L'itérateur fourni reste valable non???

    2) L'itérateur étant constant, peut-on appeler une fontion
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    supprimeElement(iter->second)
    sachant que iter-> second représente un objet Point valide pour la fonction supprimeElement (Point & point){ ... } ?

  12. #12
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    1) Ca dépend du conteneur. Pour un std::map, cela n'invalide que les itérateurs pointant vers les éléments supprimés.
    De manière générale ton interface aura les mêmes contraintes que le conteneur sous-jacent, càd que l'utilisateur devra prendre les mêmes précautions que s'il utilisait directement un std::map. Ce qui me paraît très honête.

    2) Non. Un const_iterator pointera vers un const Point, donc impossible de l'utiliser en tant que Point& ou Point*.
    Mais ta fonction de suppression a-t-elle réellement besoin de modifier le point reçu en paramètre ?

  13. #13
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    1) Ok Super. Ca me parait honnête également!

    2) C'était juste une question que je me suis posé. Je ne compte pas l'utiliser.

    J'ai donc choisi de renvoyer un itérateur. J'ai fait un premier programme de test, tout fonctionne correctement.

    Merci à toi Laurent, ainsi qu'à ZaaN !

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

Discussions similaires

  1. std::map::find
    Par Blowih dans le forum SL & STL
    Réponses: 12
    Dernier message: 21/12/2005, 19h42
  2. Accession aux std::map triées ?
    Par Matthieu Brucher dans le forum SL & STL
    Réponses: 5
    Dernier message: 18/11/2005, 14h44
  3. std::map<int,CStringArray> ????
    Par philippe V dans le forum MFC
    Réponses: 1
    Dernier message: 12/10/2005, 06h48
  4. Libérer des pointeurs dans une std::map
    Par GaldorSP dans le forum SL & STL
    Réponses: 2
    Dernier message: 09/07/2005, 14h42
  5. Trier un std::map selon les valeurs plutot que les clés
    Par dj.motte dans le forum SL & STL
    Réponses: 2
    Dernier message: 13/11/2004, 21h54

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