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 :

Polymorphisme + New


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut Polymorphisme + New
    Les classes:
    J'ai une classe abstraite Individu puis deux classes héritant de cette classe Individu, Homme et Femme.

    Maintenant j'ai une classe listIndividu et j'ai envie de créer une fonction
    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
     
    class listIndividu
    {
    public:
    Individu * list;
    Individu * new_individu_size(Individu * ind,int n)
    {
       return list =  new ???[ n]; // la je veux créer n femmes ou hommes 
    //selon la liason du pointeur dynamique
     
    }
    };
    int main()
    {
    Femme* f;
    listIndividu list;
    list.new_individu_size(f,3);
     
    }
    Comment faire???

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    Est-ce assez clair???

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    349
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 349
    Par défaut
    Citation Envoyé par vincho
    Est-ce assez clair???
    Pas vraiment, tu veux faire quoi exactement? Une liste chaînée d'individus?

    Remarque que pour utiliser le polymorphisme avec un tableau, tu es obligé d'utiliser un tableau de pointeurs:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Individu *tab[2];
    tab[0] = new Femme();
    tab[1] = new Homme();
    Pour t'aider plus précisément il faudrait plus d'informations sur ce que tu essaies de faire...

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    Je veux créer une liste d'individu correspondant au pointeur de la liaison dynamique de l'argument de la fonction new_individu_size.

    En vérité, je travaille en traitement d'images, et je voudrais créer une image qui est une liste de voxel sachant que les voxels peuvent être différents.
    donc:
    une fonction new_voxel_size quelques soient le voxel

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    Et à la compilation je ne sais pas quel type de voxel ou d'individu (Homme ou femme), la liste va contenir.

    C'est à l'éxécution que la lister va créer une liste de femme ou d'homme...

    c'est pourquoi je veux faire appel à une fonction:
    new_individu_size(Individu * ind,int n)
    et selon le lien dynamique creer le bon type

  6. #6
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Citation Envoyé par vincho
    Comment faire???
    Tu peux faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class listIndividu
    {
    public:
    	Individu * list;
    	template<typename T>
    	Individu * new_individu_size(T* ind,int n)
    	{
    	   return list =  new T[ n];
    	   // ici tu remplis ton tableau
    	}
    }
    Mais ton code est bizare, on peut imaginer un cas dans lequel ce conteneur que tu fais ait un sens, mais il s'agit d'un cas tout de même assez alambiqué.

    Le code que j'ai écris ci-dessus compile et peut marcher, si tu sais VRAIMENT ce que tu fais. Mais c'est pas très joli joli.

    Si tu débutes en C++ et que tu veux utiliser un tableau de taille variable, tu devrais te documenter ici
    plutot que d'essayer d'en faire un toi-même.

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    349
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 349
    Par défaut
    Ton image tu connais sa taille, elle a par exemple m*n voxels? Dans ce cas, comme j'ai fais plus haut, tu pourrais faire un tableau de pointeurs de taille m*n.

  8. #8
    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 : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    De toute évidence c'est ton instance qui va savoir si elle est un homme ou une femme ; c'est donc à elle qu'il va falloir demander de créer des instances du même type. C'est en quelque sorte une extension du design pattern du clone.

    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
    25
    26
    27
    28
    class Individu
    {
    public :
     
        virtual Individu* Clone(int Count) = 0;
    };
     
    class Homme : public Individu
    {
    public :
     
        virtual Individu* Clone(int Count) {return new Homme[Count];}
    };
     
    class Femme : public Individu
    {
    public :
     
        virtual Individu* Clone(int Count) {return new Femme[Count];}
    };
     
    Individu * new_individu_size(Individu * ind, int n)
    {
        if (ind)
            return ind->Clone(n);
        else
            return NULL;
    }

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    Merci de vos réponses:

    Je vais garder la solution de Feriaman car elle me permet de ne pas définir pour chaque class Homme, Femme, enfants, chiens, cochons... la fonction clone que me propose Laurent Gomila.

    Encore Merci,
    Ca compile, Youpi!!!!!!!!!!

  10. #10
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    J'aurais mieux fait de me taire.

    Le code que j'ai écris ci-dessus compile et peut marcher, si tu sais VRAIMENT ce que tu fais. Mais c'est pas très joli joli.
    Ma "solution" n'est pas bonne, et elle va poser un certain nombre de problèmes par la suite.

    Notament, tu vas devoir caster ta liste avant de t'en servir.
    Tu ne dois pas utiliser cette solution.

  11. #11
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    J'explicite : ta variable list "croit" qu'elle pointe sur un tableau de A, alors qu'elle pointe sur un tableau de B, elle n'est donc pas capable de retrouver ses propres éléments, du coup, ce code :
    renvoie n'importe quoi et surtout pas le second élément du tableau.

    Le premier élément du tableau serait renvoyé par exemple par :
    si c'est un tableau de femmes.

    C'est très moche comme solution.

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    Merci, je vais donc implanter clone dans chacune des classes!!!!

    Je croyai que la force de C++ était de pouvoir s'abstenir d'écrire n fois la même fonction; ici clone.
    J'aurai du rester au C pure

  13. #13
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Avec tout le respect que je dois à Laurent Gomila, cela ne changera rien du tout.

    Le problème vient du fait que tu stockes un tableau de "Homme" dans un pointeur de "Individu"... quel que soit la façon dont tu génère ton tableau, le problème de l'adressage restera le même.

    Ce que je te propose (si vraiment tu ne veux pas utiliser les conteneurs de la stl comme mentionné plus haut), c'est de faire quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      class listIndividu
    {
    public:
    	Individu ** list;
    }
    Après, tu peux créer ton tableau selon la méthode de Laurent ou en utilisant la méthode template décrite plus haut.
    (quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ...
    template<typename T>
    	Individu * new_individu_size(T* ind,int n)
    	{
    	   return list =  new T*[ n];
    	   // ici tu remplis ton tableau
    	}
    ...
    à noter : le new T*[n] qui crée non pas un tableau d'éléments, mais un tableau de pointeurs)

    La différence réside dans le fait que ta liste n'est plus une liste d'individus, mais une liste de pointeurs d'individus.

    Or tous les pointeurs ont la même taille, donc ton tableau saura repérer son contenu. Et donc :
    retournera bien un pointeur du second élément.

    Attention quand même, si tu fais ceci, il te faut faire des new et des delete pour chaque élément de ton tableau.

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    Comment faire si l'on veut que list soit de type vector de la librairie stl

  15. #15
    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 : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Tu lis les bonnes Q/R dans la FAQ C++, les tutoriels STL que l'on héberge, tu suis les liens donnés dans la FAQ vers les docs de référence, et/ou en dernier recours tu appelles ton ami Google.

    Bref il y a largement de quoi faire.

  16. #16
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 287
    Par défaut
    Je lis plein de trucs bizarre.
    Reprennons.
    Tu veux :
    a- une liste d'individus (hommes et femmes mélangés)
    b- ou alors une liste d'hommes seulement ou de femmes seulement ?

    a- => std::vector<individu*> (le "*" est très important)

    b- Plus compliqué. Je verrais bien un truc du genre
    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
    25
    26
    27
    28
    29
    30
    31
    struct ListeIndividus : boost::noncopyable
    {
        virtual Individu & operator[](int p) = 0;
        virtual Individu const& operator[](int p) const = 0;
    ... à compléter en fonction des besoins
    };
     
    template <class TypeIndividu>
    struct Liste : ListeIndividus
    {
        virtual TypeIndividu & operator[](int p) { return m_liste[p]; }
    ...
    private:
        std::vector<TypeIndividu> m_liste;
    };
     
    ....
    boost::scoped_ptr<ListeIndividus> liste;
    switch (QuoiFaire) {
    case hommes:
        liste.reset( new Liste<Homme>(...) );
        break;
    case femmes:
        liste.reset( new Liste<Femme>(...) );
        break;
    default:
        assert( ! "Choisir homme ou femme");
    } // switch
     
    Individu & i = (*liste)[41];
    i -> manger(pain);
    Il y a dans ces quelques lignes, une quantité abominable de problèmes que j'ai réussi à masquer -- et encore, j'ai pu en louper.
    Cela sent furieusement le moisi.

    Tu es sûr d'avoir besoin d'un polymorphisme résolu dynamiquement (i.e. à l'exécution) ? Si tu réponds "non", en virant à 100% templates, il y a moyen d'avoir un design propre qui soit exploitable je pense. Et potentiellement plus rapide par élimination des virtuals.


    (Au fait, j'ai vu qu'adobe.GIL a été accepté dans boost -> bibliothèque de manipulations d'images)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  17. #17
    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 : 50
    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
    Par défaut
    Je pense qu'une des premières question à se poser est si la structure de classe avec individu/homme/femme a du sens, par rapport à l'alternative qui serait une classe individu avec une donnée membre sexe. Si non, ça doit encore simplifier les choses.
    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.

  18. #18
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    Pour la question pourquoi pas mettre une instance sexe, je dis que l'exemple choisi avais juste la volonté de clarifier mon problème.... ( ce que je veux faire, c'est un tableau, image générique où l'on peut ranger les n objets d'une classe quelqu'on que).

    Ou en d'autre mots:

    Pour toute Class T,
    je veux créer un tableau qui est une collection d'objet de la class T
    tableau = (objet1,....,objetn)/{pout tout objet i appartient à T}


    Ce tableau sera fixe une fois créer, en revanche je veux pour voir saisir n'importe que élément. C'est pourquoi je voulai faire appel à vector.

    En revanche, faire appel à un tableau de pointeur qui pointe vers chaque objet ou voxel est pour moi une perte de mémoire.
    Taille occupé de mémoire = n*(size(pointeur)+size(objet))

    Or mon travail est fait sur des images 3D de taille 1024*1024*1024.

    En C, je faisai pour le type int par exemple ( int * x= (int*) malloc(sizeof(int)*n) )

    A la question résoudre à la compilation ou l'exécution, je dis que j'ai une librairie de traitement d'image en C qui repose sur deux uniques notions
    - Pouvoir parcourir l'ensembles des points/objets de l'espace
    - Pouvoir obtenir les points/objets associées au voisinage d'un point.

    Les espaces digitales répondant à ces deux contraintes sont par exemplet un graph,un maillage pavé ou héxagonale....

    Ce qui m'embéter en c, c'est que pour chaque type/espace, je devais réecrire l'ensemble des fonctions.

    C'est pourquoi j'ai pensé au C++.
    Avoir deux modules:
    1:librairie de traitement d'image reposant sur voisinage et pour tout point
    2:espace

    Lors de l'appel de la fonction voisinage d'un point dans la librairie de traitement d'image, on sait(je pense) avant l'éxecution quel est l'espace car on donne le lien dynamique Space * unSpace.
    ListdePoint = unSpace->voisinage( unSpace->Point(4) )

    Merci si vous pouvez me répondre

  19. #19
    Membre chevronné
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    349
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 349
    Par défaut
    Citation Envoyé par vincho
    En revanche, faire appel à un tableau de pointeur qui pointe vers chaque objet ou voxel est pour moi une perte de mémoire.
    Taille occupé de mémoire = n*(size(pointeur)+size(objet))

    Or mon travail est fait sur des images 3D de taille 1024*1024*1024.
    Une taille pareil ça te fait un millard d'elément, t'espères pas tout stocker un RAM j'espère? Si chaque élément est un int par exemple, certainement codé avec 4 octets (c'est assez classique), ça te fait déjà 4Go
    Et comme tu parles d'objets, c'est certainement encore plus complexe qu'un simple int, donc encore plus gros en mémoire?


    Citation Envoyé par vincho
    Pour toute Class T,
    je veux créer un tableau qui est une collection d'objet de la class T
    tableau = (objet1,....,objetn)/{pout tout objet i appartient à T}
    Pour ton problème, si chaque objet est de même type, qu'est ce qui t'empêche de faire un bête tableau?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaClass tableau[nombreElements];
    Par contre si tu veux faire du polymorphisme avec ton tableau, je me permets de réitérer mon code de ci-dessus:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Individu *tab[2];
    tab[0] = new Femme();
    tab[1] = new Homme();
    Où Femme et Homme sont des sous-class de Individu.

  20. #20
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Par défaut
    Pour le problème de mémoire, le laboratoire où je suis à une station de travail de possédant 16 giga de mémoires vives.

    Pour ton truc, je veux faire appel à vector mais le problème est ???
    vector<type_individu>

Discussions similaires

  1. Polymorphisme, new et reference
    Par Bouteille dans le forum Langage
    Réponses: 5
    Dernier message: 11/01/2012, 12h08
  2. Réponses: 4
    Dernier message: 24/03/2004, 12h37
  3. Database new user & create table
    Par MFDev dans le forum InterBase
    Réponses: 3
    Dernier message: 30/09/2003, 20h47
  4. Bug new build ??
    Par rgarnier dans le forum XMLRAD
    Réponses: 4
    Dernier message: 31/01/2003, 10h30
  5. [] Insérer DE et Datareport existant ds new projet
    Par khany dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 10/01/2003, 09h52

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