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 :

[Debutant] Utilisation d'une map pour stocker les caractéristiques d'un objet


Sujet :

SL & STL C++

  1. #1
    Candidat au Club
    Inscrit en
    Février 2008
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut [Debutant] Utilisation d'une map pour stocker les caractéristiques d'un objet
    Bonjour,

    J'ai une questions que j'aimerais vous soumettre.
    Voilà, j'ai créé un objet qui a des caractéristiques que je regroupe dans des sous catégories:
    * forme ( poids, volume, dimensions...)
    * composition chimique (nombre de carbone, formule, nom...)
    * propriétés mécaniques (traction, résistance, rugosité...)
    * propriétés électriques (conductance, inductance...)

    J'ai potentiellement une bonne 100aine de caractéristiques.

    Ensuite, j'ai plein de fonctions qui vont prendre les caractéristiques de l'objet pour en déduire d'autre grandeur.

    Je pense utiliser une map pour stocker tout au même endroit.
    Par exemple:
    <"Poids",4.5>
    <"Nb_Carbone",12>
    <"Formule", "C12H26">
    <"Nom","Dodecane">
    etc...


    En effet, cela me permettra d'être souple en n'utilisant que les infos qui sont à ma disposition (par exemple, je ne connais pas la rugosité...donc, rien dans ma map).
    Au niveau du dev, pas besoin de recompiler dès que je rajoute un attribut et surtout, je peux proposer des interfaces simples avec l'extérieur.

    Puis-je avoir votre avis sur cette conception svp ?
    Merci d'avance.

  2. #2
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Oui, ça parait une bonne idée, maintenant comment comptes-tu gérer le fait que les données associées ne sont pas du même type ?

  3. #3
    Invité
    Invité(e)
    Par défaut
    Boost.Any est fait pour cela.

    C'est une bonne idée de conception. Tu peux peut-être formaliser l'idée qu'un tel objet appartient à plusieurs "classes" (pas au sens statique, mais au sens conceptuel) dans ta conception, histoire de structurer un peu les concepts que ton application utilise, mais sinon je pense que le choix est bon. Tu auras notamment de gros avantages pour le stockage persistant de tes objets (dans une base de données, par exemple, qui s'y prêterait bien).

    Carl

  4. #4
    Candidat au Club
    Inscrit en
    Février 2008
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    Oui, ça parait une bonne idée, maintenant comment comptes-tu gérer le fait que les données associées ne sont pas du même type ?
    Merci. Effectivement, les données gérées ne seront pas du même type.
    Les fonctions qui prennent en argument la map utiliseront "le bon type".
    Par ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    getName (CaracMap _carac)
    {
          return _carac("Nom");
    }
     
    computeNbHydrogene (CaracMap _carac)
    {
          long nbH = _carac("Nb_Carbone") * 2;
          if _carac("Type") == "Alcane"    
               return nbH + 2;
    }
    Le danger c'est qu'à la compilation, ça ne vérifiera pas qu'on ajoute des choux et des carottes !

    Citation Envoyé par 5hdumatin Voir le message
    Boost.Any est fait pour cela.

    C'est une bonne idée de conception. Tu peux peut-être formaliser l'idée qu'un tel objet appartient à plusieurs "classes" (pas au sens statique, mais au sens conceptuel) dans ta conception, histoire de structurer un peu les concepts que ton application utilise, mais sinon je pense que le choix est bon. Tu auras notamment de gros avantages pour le stockage persistant de tes objets (dans une base de données, par exemple, qui s'y prêterait bien).

    Carl
    Merci pour ton analyse.
    Je ne comprends pas trop ta recommendation, tu peux me donner un exemple stp ?

    Autre point, est-ce vraiment une conception objet ? car je me demande si finalement, on a pas un fourre-tout !

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Si tu peux la plupart du temps manipuler tes données de manière uniforme, en te moquant du fait que l'une représente la résistance, l'autre la capacité, ce design ne me choque pas.

    Si tel n'est pas le cas, si tu dois sans cesse tout au long du logiciel travailler avec telle puis telle donnée, ce design me semble plus douteux.

    Par exemple, si je reprends les données électriques, si le but est de gérer un catalogue de composants, ok. Si le but est de gérer un simulateur de schéma électrique, je suis moins convaincu.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Hello tof114,

    C'est ta conception, et sans avoir les détails du programme, c'est difficile de venir avec des éléments concrets, surtout lorsque ta solution est particulièrement abstraite.

    Imagine qu'une partie de ton logiciel est, comme le mentionne JolyLoic, un simulateur de schéma électrique. Cette partie-là de l'application ne va gérer qu'un sous-ensemble des propriétés de chaque objet, et va ignorer les autres. Peut-être que cette subdivision peut apparaître dans le code c++, sous forme d'adaptateurs, par exemple, qui "enveloppent" ton type très général dans une interface C++ plus stricte et plus spécialisée, dans le but de faciliter la manipulation.

    Par contre, quand je regarde l'interface que tu proposes, j'ai l'impression que tu adoptes la solution perdant-perdant: tu as une interface définie à la compilation, et donc tu perds par exemple en capacités d'introspection, mais tu as une implémentation "relax" qui inhibe toute vérification sur les types et toute optimisation de la part du compilateur. Si j'étais toi, j'aurais une classe "Objet" qui propose des méthodes de manipulation très générale sur les propriétés (y compris de lister les propriétés et de vérifier si une propriété a bien été définie) et un ensemble de classes "adaptatrices" pour utiliser de tels objets dans tel ou tel contexte.

    Pour ton problème de type, je te conseille vivement Boost.Any: si tu as des fonctions différentes comme tu l'indiques, chaque fonction récupère la donnée grâce à son nom, et vérifie le type à la compilation avant de renvoyer la valeur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    std::map<std::string, boost::any> carac_t;
     
    std::string getName(carac_t& caracs)
    {
      // Lance une exception si la carac "Nom" n'a pas le type
      // std::string (ou compatible).
      return boost::any_cast<std::string>(caracs["Nom"]);
    }
     
    int getNbHydrogene(carac_t& caracs)
    {
      return boost::any_cast<int>(caracs["Nb_Carbone"]);
    }
    Carl

  7. #7
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    C'est le principe du variant. On a ça aussi chez nous pour lire depuis la base de données.

    Je suis curieux de voir l'implémentation de boost. J'y jetterai un coup d'oeil quand je pourrais.

  8. #8
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    C'est le principe du variant. On a ça aussi chez nous pour lire depuis la base de données.

    Je suis curieux de voir l'implémentation de boost. J'y jetterai un coup d'oeil quand je pourrais.
    Y as des différences dans boost entre le any et le variant

    http://www.boost.org/doc/html/varian...ant.versus-any

  9. #9
    Candidat au Club
    Inscrit en
    Février 2008
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    On a ça aussi chez nous pour lire depuis la base de données.
    Est-ce que ça veux dire que vous ouvrez un curseur sur un produit, que vous fetchez les caractéristiques en utilisant une map telle que std::map<std::string, boost::variant> carac_t; ?


    Si oui, comment est-ce que vous avez implémenté la suite, c'est à dire l'utilisation des données qui seront contenues dans la map ? avec des get ?

    Merci.

  10. #10
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Salut,

    c'est du code qui a été écrit il y a une dizaine d'année, je ne suis là que depuis 2 mois et je ne maîtrise que le haut niveau de l'appli, et encore, juste ce dont on a besoin de maintenir.

    Mais pour cette partie oui, si besoin, on a créé, dans les classes représentant les tables de notre base, une map de "champs" associés à des noms. Ces champs sont sans véritable type.

    On peut faire correspondre l'interface graphique et un champ en donnant un Control MFC au champ, et on utilise des méthodes ToControl ou FromControl pour mettre à jour le champ ou l'interface. Parallèlement à ça on doit donner un buffer (void*) pointant vers un curseur de la base au champ qui écrit directement dedans au moindre changement. Il ne reste qu'à faire un Update() sur le curseur si on veut mettre à jour.

  11. #11
    Candidat au Club
    Inscrit en
    Février 2008
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Ok, merci à tous pour vos analyses et conseils.

    Je clos le thread.
    A+

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

Discussions similaires

  1. Utiliser une Map pour stocker des informations
    Par sonia5 dans le forum Collection et Stream
    Réponses: 14
    Dernier message: 21/09/2011, 14h35
  2. Réponses: 1
    Dernier message: 04/02/2010, 11h45
  3. Réponses: 1
    Dernier message: 13/09/2009, 23h51
  4. Utiliser une variable pour stocker les noms d'objets.
    Par en_gel_ho dans le forum Access
    Réponses: 4
    Dernier message: 03/01/2007, 16h44
  5. Réponses: 5
    Dernier message: 26/05/2005, 15h40

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