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

Langage C++ Discussion :

Affectation objet type de base


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 366
    Par défaut Affectation objet type de base
    Bonjour a tous,

    L'intitulé n'est pas tres clair mais voici ma question.

    J'ai une classe Objet dont hérite Objet1 Objet2 Objet3 etc..

    J'ai une map d'Objet* qui me permet de stocker mes differents Objet[1-2-3]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::map<std::string, Objet*>
    Quand je veux utiliser cette map je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Object * pObj = getObjInMap( "MaCle" );
    if( dynamic_cast<Objet1*>(pObj) )
    {
    }
    else if( dynamic_cast<Objet2*>(pObj) )
    {
    }
    else if( dynamic_cast<Objet3*>(pObj) )
    {
    }
    Et pour copier ma map je pense faire:
    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
     
    std::map<std::string, Objet*>const_iterator it;
    for(it = mMaMap.begin(); it!=mMaMap.end(); it++)
    {
        if( dynamic_cast<Objet1*>(it->second) )
        {
            Objet1 * pObj = new Objet1(it->second);
        }
        else if( dynamic_cast<Objet2*>(it->second) )
        {
            Objet2 * pObj = new Objet2(it->second);
        }
        else if( dynamic_cast<Objet3*>(it->second) )
        {
            Objet3 * pObj = new Objet3(it->second);
        }
    /*
        Copie de l'objet cree dans la nouvelle map
    */
    }
    Mais je trouve pas ça super dans le sens ou chaque objet qui herite de Objet je devrais rajouter des entrees dans toutes ces methodes.
    Est ce vraiment comme ça qu'il faut faire ou bien y a t il une autre maniere ?

    Merci d'avance

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    1. Es-tu obligé de faire un unique map ? Utilises-tu, à un endroit de ton code, le polymorphisme sur ce conteneur ?

    2. Problème annexe : ne peux-tu utiliser autre chose qu'un string comme clé de ton map ?

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 366
    Par défaut
    Citation Envoyé par oodini Voir le message
    1. Es-tu obligé de faire un unique map ? Utilises-tu, à un endroit de ton code, le polymorphisme sur ce conteneur ?
    Tres bonne remarque, car je viens de voir que non..
    C'est juste que chaque Objet possede cette map qui lui permet de stocker d'autre objets enfants. Cela donne un arbre de donnees a base de Objet[1-X].
    Le probleme c'est que si je veux redefinir l'affectation d'un Objet, je dois recopier tout ses objets enfants de cette map.
    Problème de conception ?
    D'ailleurs je me suis trompe dans mon premeir post mais ca ne change pas le probleme:
    Chaque Objet a une map
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::map<std::string, ObjectList*>
    Qui contient une liste chainee de ses objets donc en clair:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Objet------> MapObjet1-----------> instance 1 Objet1
    -----------------------------------> instance 2 Objet1
    ------------>MapObjet2------------> instance 1 Objet2
    ------------>MapObjet3------------> instance 1 Objet3
    // Avec Objet de type Objet
    //         MapObjet1 liste chainee de type Objet*
    Citation Envoyé par oodini Voir le message
    2. Problème annexe : ne peux-tu utiliser autre chose qu'un string comme clé de ton map ?
    Donc en fait la string de la map permet de savoir quel sous objet je recherche


    @r0d: Je vais regarder ce principe de constructeur virtuel, je n'ai jamais utilisé et ne connais pas ce principe.

    @leternel: Perdre l'info trop vite, ok, mais comment faire ? Mettre un static membre dans Objet permettant de savoir de quel type est réellement l'objet ? Cela revient en quelque sorte a tenter du dynamic_cast non ? A moins que je vois mal ce que tu voulais dire

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Les informations que tu donnes ne sont permettent pas de conclure.
    Mais je serais toi, je réfléchirai s'il n'y a pas moyen de se passer de polymorphisme.

    Citation Envoyé par sone47 Voir le message
    Donc en fait la string de la map permet de savoir quel sous objet je recherche
    Il faut toujours éviter de mettre un string comme clé. C'est coûteux. Essaye de voir si un enum ne serait pas plus indiqué.
    Cela dit, si tu n'es pas dans un traitement répétitif, ce n'est pas forcément gênant.

  5. #5
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    ça dépend du contexte, mais une solution qui fonctionne généralement est le constructeur virtuel (ou clone idiom).
    Je viens juste d'implémenter un conteneur d'objets polymorphes en utilisant ce pattern, et ça marche bien. L'inconvénient principal est qu'il te faut implémenter une fonction clone() pour chaque classe dérivée.

  6. #6
    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
    Dans ce cas, tu peux envisager le clonage.

    Tu liras alors avec intérêt ces deux points de la faq:
    la copie polymorphique

    le retour covariant

    ou encore, lire le lien fourni par r0d:
    Citation Envoyé par r0d Voir le message
    Bonjour,

    ça dépend du contexte, mais une solution qui fonctionne généralement est le constructeur virtuel (ou clone idiom).
    Je viens juste d'implémenter un conteneur d'objets polymorphes en utilisant ce pattern, et ça marche bien. L'inconvénient principal est qu'il te faut implémenter une fonction clone() pour chaque classe dérivée.
    À mon avis, ton problème vient de ce que tu implémente un arbre "générique trop tôt"

    Si ton information était correctement structurée (par les bonnes classes), chaque nœud aurait une sémantique choisie, et fournirait les informations utiles et réelles.
    Que veux-tu représenter réellement?

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 366
    Par défaut
    Merci pour vos reponses,

    J'ai regardé les liens pour la copie polymorphe et les retours covariants,
    Il faut que je regarde la compatibilité avec Visual 2010 et GCC 4.1.2.

    @leternel je comprend ta remarque sur le fait de perdre trop tot l'info mais le probleme c'est que je ne vois pas comment faire autrement :/

    @oodini:

    En fait voici l'utilisation que j'ai de ces objets:

    Objet: Classe de base de mes objets
    Objet[1-X]: Objet sur lesquels je travail

    Chaque Objet peut posseder X Objets enfants, classés dans des listes chainées selon leur type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Objet::map<std::string/*pour le type*/, ObjectList /*liste chainee d'objet de type Objet1 ou Objet2...*/>
    Chaque objet peut donc recuperer son n-ieme enfant de type ObjetX ou son objet parent.

    J'utilise 2 methode sur ce conteneur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    addChildren( "Objet1", Objet1*) // Mais du coup quand je fais un add le type est donne car determine par la string..
    getChildren( "Objet1") // Qui me renvoi la liste chainee de mes objets de type Objet1

  8. #8
    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
    Une map ne contient que des "trucs qui passent pour des objets"

    Vouloir chercher le type exact d'un objet signifie qu'on a perdu trop vite cette information!

    Il y a deux solutions classiques: augmenter l'interface de base (ici, Objet) et diversifier les conteneurs.

    Si tu augmentes objet, tu pourras profiter de l'héritage efficacement.
    Si tu utilises trois maps, plutôt qu'une seule, tu pourras utiliser le type dérivé directement.

    [edit]edit trop rapide, il y a des réponses derrière[/edit]

Discussions similaires

  1. Python: différence type de base et objet ?
    Par cal23 dans le forum Général Python
    Réponses: 4
    Dernier message: 18/08/2014, 19h26
  2. Liste des types objet de la base
    Par SheikYerbouti dans le forum Contribuez
    Réponses: 0
    Dernier message: 30/12/2011, 15h25
  3. [héritage] cast avec le type de base
    Par Lere dans le forum C++
    Réponses: 6
    Dernier message: 16/09/2004, 18h21
  4. [FileMaker 6] Questions urgente sur type de base de donnee
    Par LAPLACE dans le forum Autres SGBD
    Réponses: 2
    Dernier message: 06/09/2004, 17h39
  5. [CR]Changement de type de base de donnée
    Par nabil dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 12/04/2004, 22h42

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