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 :

Heritage et type de retour des methodes


Sujet :

C++

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 13
    Par défaut Heritage et type de retour des methodes
    Bonjour a tous, ca fait un peut de temp que j'essaie de resoudre ce probleme -_- mais rien a faire

    Voila j'ai une methode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual Noeud& filsGauche()  =0;
    define dans una classe abstrate Noeud

    Ce une reference, mais etant abstraite je n'ai pas trouve autre chose pour eviter que G++ ne rale.

    Maintenant je cree la classe NoeudV et je veut redefinir la methode:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    NoeudV& filsGauche() {return NoeudV(2*index+1,infos);}
    Bon ca ne marche pas, car on renvoie un NoeudV& qui est une reference vers un temporaire qui n'existe plus, alors je met

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    NoeudV filsGauche() {return NoeudV(2*index+1,infos);}
    Mais il aprecie pas, il trouve que ce pas la meme -_- or si j'avait bien compris le type de retour n'est pas dans la signature de la fonction...

    Comment faire :'(

  2. #2
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    Salut,

    Le type de retour fait partie de la signature de la fonction.

    Donc quand tu redéfinis une fonction virtuelle, il faut que le type de retour soit le même. La seule exception à cette règle : le type de retour de la fonction redéfinie peut être un type dérivé du type de retour de la fonction virtuelle. Mais dans ce cas il faut manipuler la variable de retour de manière "polymorphe" autrement dit via un pointeur ou une référence.

    En effet, si B dérive de A, il est possible d'affecter un B* à un A* ou un B à un A&, d'où cette possibilité de changement de type. Par contre il n'est pas possible d'affecter un B à un A.

    Si tu utilises une référence, tu n'as pas le choix, il faut que ta variable soit initialisée avant. Sinon tu peux retourner un pointeur et allouer celui-ci dans le corps de ta fonction avant de le retourner, mais je n'aime pas trop cette méthoe, l'ownership du pointeur est transférée de manière implicite.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 13
    Par défaut
    mmm mais pour l'avoir declarer avant ce n'est pas tjr evident non?
    Et je ne voit pas comment faire en tout cas dans le cas de ma classe ^^'

    Pour les pointeur, j'immagine donc que faire une methode qui fait directement un return ce n'est plus bon ^^"

    Mais pourquoi tu n'aime pas cette facon deja? (ce un travail pour mes cours donc si il y a des truc pas bien faut que jepuisse le savoir pour ecrire un code propres)

    Merci d'avance

  4. #4
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Le type de retour ne fait PAS partie de la signature de la fonction - pas au sens recherche de fonction qui va bien -, en revanche, il est analysé dans le cas d'une hiérarchie pour avoir une cohérence - le type de retour d'une hiérarchie fille doit hériter du type de retour dans la hiérarchie parente -. Et une référence transformée en non référence, ce n'est pas le même type, donc c'est dans le dernier cas que ça plante.

  5. #5
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    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 296
    Par défaut
    Le polyrmohisme d'inclusion (en C++: héritage + redéfinition de fonctions membres virtuelle) ne me parait pas être ce qu'il y a de plus indiqué pour définir des arbres. Au contraire du polymorphisme paramétrique (C++: templates).

    Mais passons. De tous les arbres que j'ai manipulés, les noeuds existaient déjà avant qu'on les cherche et renvoie. Et du coup, après seuls des pointeurs se balladent.
    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...

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 13
    Par défaut
    les template rentrerons dans un deuxieme temp ^^ ce un travail d'ecole j'ai donc des conigne a respecter.

    Mais j'envisage la solution avec des pointeur, meme si j'ai jamais vu ce gendre de code.

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual std::auto_ptr<Noeud> filsGauche()  = 0;
    Par exemple.

    Mais c'est bien sûr pas très bon.
    Je vois pas pourquoi tu devrais utiliser de l'héritage pour indiquer différents types de noeuds. Tout ce que tu peux différencier c'est les noeuds sans fils, sans fils gauche, sans fils droit, et avec les deux.

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 13
    Par défaut
    oO et ce quoi ca?

    Tu n'aurait pas un lien vers un tuto qui explique stp?

  9. #9
    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
    Ma foi, dans ce cas, les différents noeuds (fils doit, fils gauche, les deux) "sont des" noeuds trés clairement non?

    Sinon, si NoeudV hérite de Noeud, ta fonction peut, tout simplement, renvoyer un Noeud. C'est à la déclaration que tu spécifiera que c'est un noeudV (ou autre).

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 13
    Par défaut
    Oui ce des noeud.

    Je souligne que ce un travail pour mon cours il y a dons des regle a respecter.

    Sinon l'heritage est que il y aura des noeud ilmplemente grace a des listes. et pas des vecteur

  11. #11
    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
    Je ne comprends pas trop ce que tu as écris. Est-ce une question?
    De façon générale, tu ne nous fournis pas assez de détails pour que l'on puisse répondre efficacement à ton problème, et, plus généralement, je te demanderais de faire un effort dans la rédaction de tes messages.


  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 13
    Par défaut
    desole.

    Et bien oui, le fils gauche, fils droit ce bien des noeuds.

    En effet on a un arbre, et on a une methode qui renvoie la racine.
    On decide alors d'aller sur le fils gauche on a donc un nouveau noued qui est cree qui contien les info pour acceder au fils gauche de la racine.

    Le noeud " reste le meme " dans tout les cas, meme si il represent un Element d'une liste ou d'un vecteur.

    Mon probleme concerne le type de retour, je ne connait pasles auto_ptr et je demandait s'il n'y avait pas un tuto qui en parlait. voila j'espere etre plus clair

  13. #13
    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
    Ok, merci pour ce joli post

    Etant donné que tu es dans le cadre d'un exercice, je te déconseille d'utiliser un auto_ptr, pour plusieurs raisons dont celle que c'est inutile dans ton cas (à moins que je n'ai pas tout compris au problème, ce qui reste une éventualité dont la probabilité n'est pas négligeable).

    Comme je le disais dans un précédent post, si tu as NoeudV qui hérite de Noeud, le plus simple est que ta fonction retourne un Noeud, autant la fonction virtuelle "mère" que celles qui en hériteront. Ainsi, tu auras:

    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
    class Noeud
    {
    [...]
    virtual Noeud* FilsGauche() = 0; //reste à voir si tu souhaite obtenir un pointeur ou directement un objet
    [...]
    };
     
    class NoeudV : public Noeud
    {
    [...]
    Noeud* FilsGauche(); //cette fonction étant implémentée dans le .cpp correspondant
    [...]
    };
     
    class NoeudX : public Noeud // un autre type de noeud, pour l'exemple
    {
    [...]
    Noeud* FilsGauche(); //cette fonction étant implémentée dans le .cpp correspondant
    [...]
    };
    Ainsi, tu pourras appeler FilsGauche indépendamment du type réel de ton noeud. Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    NoeudV* noeudv = new NoeudV(/*parametres si besoin est*/);
    noeudv  = MonArbre.FilsGauche();
    NoeudX* noeudx = new NoeudX(/*parametres si besoin est*/);
    noeudx  = MonArbre.FilsGauche();
    hope it helps.

  14. #14
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 13
    Par défaut
    mmm oui ca rassamble a ma premiere version.

    Par contre dans l'implementation de Filsgauche je fesait un new.

    Et je ne voit ou je ferait des delete ^^"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Arbre2V::NoeudV* Arbre2V::NoeudV::filsGauche(){
    	NoeudV* ptr;
    	ptr=new NoeudV(2*index+2,infos);
    	return ptr;
    }
    De la l'idee de metre des auto_ptr qui detruirait l'element

  15. #15
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Comme je le disais dans un précédent post, si tu as NoeudV qui hérite de Noeud, le plus simple est que ta fonction retourne un Noeud, autant la fonction virtuelle "mère" que celles qui en hériteront. Ainsi, tu auras:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Noeud
    {
    [...]
    virtual Noeud* FilsGauche() = 0; //reste à voir si tu souhaite obtenir un pointeur ou directement un objet
    [...]
    };
    Tu ne retournes pas un Noeud mais un Noeud*.
    Et il va s'agir d'un pointeur vers une zone dynamicallement allouée. (cf.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    NoeudV filsGauche() {return NoeudV(2*index+1,infos);}
    ) donc cela pose des problèmes de libération.

    De manière générale, les pointeurs sont à éviter dans autre chose que des parties privées.
    Si on veut référencer un truc existant, on utilise les références.
    Si on veut un truc dynamiquement alloué, il nous faut l'envelopper pour que le destructeur se charge de faire la libération en adéquation avec le RAII.

    Ainsi, tu pourras appeler FilsGauche indépendamment du type réel de ton noeud. Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    NoeudV* noeudv = new NoeudV(/*parametres si besoin est*/);
    noeudv = MonArbre.FilsGauche();
    NoeudX* noeudx = new NoeudX(/*parametres si besoin est*/);
    noeudx = MonArbre.FilsGauche();
    4 lignes, 4 fuites mémoire. (dont 2 récupérables avec du code additionnel ensuite)
    Pas mal.

  16. #16
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    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 296
    Par défaut
    Citation Envoyé par r0d
    Etant donné que tu es dans le cadre d'un exercice, je te déconseille d'utiliser un auto_ptr, pour plusieurs raisons dont celle que c'est inutile dans ton cas (à moins que je n'ai pas tout compris au problème, ce qui reste une éventualité dont la probabilité n'est pas négligeable).
    Je ne classe pas les auto_ptr comme inutiles pour signifier qu'une fonction renvoie un pointeur que l'appellant à la charge de détruire, bien au contraire. Je suis prêts à payer pour le confort sémantique qu'il apporte.

    Seulement, avec, pas de retour covariant, aucun prof qui acceptera de croire que l'élève a trouvé ça tout seul, ...
    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
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 13
    Par défaut
    Mmmm au debut je retournait un NoeudV.

    Mais comme NoudV herite d'une classe absraitre, dans la classe abstraite un virtual Noeud filsGauche()=0; ne marche pas (car on devrait appeler le constructeur leur du retourn qui dans une classe abstraite ne peut pas etre appelle)

    Donc j'avait mis des &, mais je ne voyait pas cmt m'en sortir, de l'a les pointeur, qui eux par contre marchent bien, a part le souci de la liberation.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    NoeudV* noeudv = new NoeudV(/*parametres si besoin est*/);
    noeudv = MonArbre.FilsGauche();
    Mmmm, mais dans le code de filsGauche on aurait quoi?
    Car le code que j'ai mis avant, il fait un new, il y a donc creation d'un element, qui remplacera l'actuel et donc on aurait le NoeudV() cree ici qui n'aurait plus aucun pointeur qui le pointe.

    Seulement, avec, pas de retour covariant, aucun prof qui acceptera de croire que l'élève a trouvé ça tout seul, ...
    Ce quoi un retour covariant?

    Quant a trouver le auto_ptr, il se doute bien que on demande de l'aide, de plus etant present dans la norme c++ que il nous a donne comme seule reference pour le cours j'ai tout a fait le droit de l'utiliser. (enfin j'ai quand meme pose la question au prof et j'attend la reponse)

  18. #18
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::auto_ptr<Noeud> filsGauche()
    {
        return std::auto_ptr<Noeud>(new NoeudV(2*index+1,infos));
    }

  19. #19
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 13
    Par défaut
    On utilise donc des auto_ptr ?

    Ca ne saurait pas auto_ptr<NoeudV> ?

  20. #20
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Citation Envoyé par belfo
    On utilise donc des auto_ptr ?
    Oui.

    Citation Envoyé par belfo
    Ca ne saurait pas auto_ptr<NoeudV> ?
    Non.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Type de retour des surcharges d'opérateur
    Par syl1405 dans le forum C++
    Réponses: 8
    Dernier message: 16/06/2010, 17h22
  2. creation de "TYPE OBJECT" avec des methodes
    Par TheBlackReverand dans le forum Oracle
    Réponses: 2
    Dernier message: 15/06/2009, 20h57
  3. Type de retour des WebMethod
    Par oclone dans le forum Services Web
    Réponses: 2
    Dernier message: 11/06/2009, 15h57
  4. Réponses: 6
    Dernier message: 18/04/2009, 11h37
  5. reflexion et type de retour des méthodes
    Par money mark dans le forum Langage
    Réponses: 2
    Dernier message: 09/04/2006, 18h46

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