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 :

overloader un opérateur


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 42
    Par défaut overloader un opérateur
    Salut tout le monde!
    Comme le nom de l'intitulé le dit je voudrais overloader un opérateur(le + pour être plus précis. Je travaille avec des listes chainées que j'ai codé auparavant(toutes mes fonctions fonctionnent très bien j'ai fait plein de test). Il s'agit d'un projet scolaire et voici la consigne pour l'overloading de l'opérateur :
    "L3 = L1 + L2: Creates a new linked list, called L3, which consists of L1
    and L2."
    Ma fonction est censé me créer une nouvelle liste chainé qui contiendra tout les maillons de L1 et L2 à la suite. (j'ai overloader =avant bien entendu....), donc je me concentre sur L1+L2;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SpecialLinkedList& SpecialLinkedList::operator+(SpecialLinkedList& Source)
    {
    	SpecialLinkedList New;
            New.addAll(this);     //permet de rajouter tout les maillons de this dans New
    	New.addAll(&Source);     //permet de rajouter tout les maillons de Source dans New.
    	return New;
    }
    Dans mon cas le this est L1 et Source est L2;
    Je sais que je retourne un SpecialLinkedList et que mon prototype dit que je doit renvoyer un SpecialLinkedList&, donc j'ai une incompatibilité...Mon erreur ne doit pas venir que de là(je suppose!). le compilateur me sort un avertissement qui me crash le programme à l'éxecution.Mon probleme est que je n'arrive pas à retourner un objet créer dans ma fonction...Si je lis ma liste chainée juste avant de faire le return, j'ai le résultat souhaité!
    je suis ouvert à tout conseil...peut être il y a quelque chose que j'ai mal compris...
    Je vous remercie par avance de votre aide

  2. #2
    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
    Là tu renvoies une référence sur un objet qui va être détruit dès la fin de la fonction, normal que ça crash. Lorsque tu renvoies un nouvel objet, qui n'existe pas en dehors de la fonction, il faut le renvoyer par valeur et non par référence. Ainsi il sera recopié et l'original pourra être détruit sans problème.

  3. #3
    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
    Pour ce genre de truc il serait plus intéressant d'avoir des listes immutables et de faire du partage implicite.

  4. #4
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 42
    Par défaut
    Si j'ai bien compris Laurent Gomila, tu me dis de mettre mon prototype comme tel:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SpecialLinkedList SpecialLinkedList::operator+(SpecialLinkedList& Source)
    {
    	SpecialLinkedList New;
    	New.addAll(this);
    	New.addAll(&Source);
    	New.Display();
    	return New;
    }
    je n'ai plus aucun avertissement, mais lors de l'éxecution au moment d'afficher le résultat il commence à m'afficher comme premier maillon une adresse mémoire(contrairement à un simple entier...) et ensuite est incapable de lire la suite ce qui le fait crasher!
    Ensuite:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SpecialLinkedList& SpecialLinkedList::operator+(SpecialLinkedList& Source)
    {
    	SpecialLinkedList* New=new SpecialLinkedList;
    	New->addAll(this);
    	New->addAll(&Source);
    	New->Display();
    	return New;
    }
    Ce que j'avais penser aussi était de déclarer ma nouvelle liste chainée dynamiquement comme cela elle ne se serait pas effacer, mais mon problème est que je ne sais convertir "SpecialLinkedList *" en "const SpecialLinkedList &". J'ai lus dans la FAQ et dans les tutoriels que le retour par référence est comme avec les pointeurs mais que cela n'en est pas...Dans mon dernier cas comme retourner ma liste chainé par référénce?

    loufoque, je ne comprend pas de quoi tu parle, je cherche des infos sur ce que tu m'as dit mais je ne trouve pas....comme je l'ai dit, il m'est imposé d'utiliser mes propres listes chainées, impossible d'utiliser la STL par exemple...

    Merci pour votre aide!

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Côte d'Or (Bourgogne)

    Informations forums :
    Inscription : Mai 2005
    Messages : 92
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SpecialLinkedList& SpecialLinkedList::operator+(SpecialLinkedList& Source)
    {
    	SpecialLinkedList* New=new SpecialLinkedList;
    	New->addAll(this);
    	New->addAll(&Source);
    	New->Display();
    	return New;
    }
    Ce que j'avais penser aussi était de déclarer ma nouvelle liste chainée dynamiquement comme cela elle ne se serait pas effacer, mais mon problème est que je ne sais convertir "SpecialLinkedList *" en "const SpecialLinkedList &". J'ai lus dans la FAQ et dans les tutoriels que le retour par référence est comme avec les pointeurs mais que cela n'en est pas...Dans mon dernier cas comme retourner ma liste chainé par référénce?
    Tu peux toujours terminer par un mais alors la problématique devient la suivante: comment bien libérer la mémoire allouée par ton "new SpecialLinkedList" qq part dans ton programme... ça sera peut-être pas si facile. Donc à mon avis il vaut mieux faire un retour soit par valeur, soit par pointeur.

  6. #6
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 42
    Par défaut
    Il n'y a pas de problème pour libérer la mémoire par la suite car mon destructeur s'occupe de supprimer chaque maillon de ma liste chainée. Au pire j'ai créer une fonction qui le fait(mon destructeur l'appelle!).

    Je te remercie beaucoup pour ton coup de pouce Biozic, en changeant mon retour effectivement le problème s'est résolu!!Du beau travail, ni erreur ni avertissement!Cela ma permet de comprendre un peu mieux le retour par référence!
    Je met le code final pour si un jour une personne retombe sur mon post!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SpecialLinkedList& SpecialLinkedList::operator+(SpecialLinkedList& Source)
    {
    	SpecialLinkedList* New=new SpecialLinkedList;
    	New->addAll(this);//ajoute tout les maillons de this(L1) dans ma nouvelle liste chainée
    	New->addAll(&Source);//ajoute tout les maillons de Source(L2) à la suite dans ma nouvelle liste chainée
    	return *New;
    }
    Je remercie tout ceux qui m'ont aidé!et vive developpez.net!

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Côte d'Or (Bourgogne)

    Informations forums :
    Inscription : Mai 2005
    Messages : 92
    Par défaut
    Il n'y a pas de problème pour libérer la mémoire par la suite car mon destructeur s'occupe de supprimer chaque maillon de ma liste chainée. Au pire j'ai créer une fonction qui le fait(mon destructeur l'appelle!).
    Je ne sais pas de quel destructeur tu parles. Il est bien possible que ce destructeur libère chacun des maillons, mais es-tu sûr que ce destructeur sera lui-même appelé à un moment ou à un autre? Si tu penses à celui de New, j'ai bien peur qu'il ne soit jamais appelé si tu ne fais pas qq part un delete sur cet objet, non?

    En fait ma solution était peut-être correcte du point de vue de la syntaxe, mais c'était certainement une mauvaise idée du point de vue de la conception.

  8. #8
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    En effet. En retournant une référence, on perd de vue que l'objet a été alloué dynamiquement et donc que la durée de vie de cet objet est entre nos mains.
    Ceci n'est pas fait si l'on retourne un pointeur -> il y a aura une rigueur plus importante mise en place pour cantonner cette durée de vie à celle qu'on lui réserve.

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Côte d'Or (Bourgogne)

    Informations forums :
    Inscription : Mai 2005
    Messages : 92
    Par défaut
    Moralité, quand on surcharge operator+, il n'y a pas vraiment d'autre choix que de retourner par valeur. Désolé pour le piège!

  10. #10
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 42
    Par défaut
    Oui vous avez raison le destructor ne s'appelle pas pour mon objet alloué dynamiquement, mais je le detruit à la fin de mon main()....manuellement(sans jeu de mot...)
    Par la suite la surcharge de l'operator- en a découlé de source!
    Ton piège n'en était pas un...suffit de faire un peu attention!Et il me permet de garder l effet cascade...(L1+L2+L3 par exemple)

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

Discussions similaires

  1. Réponses: 49
    Dernier message: 02/02/2013, 02h10
  2. Opérateur like
    Par Troopers dans le forum ASP
    Réponses: 3
    Dernier message: 15/09/2003, 19h19
  3. opérateur non applicable à ce type d'opérande
    Par Amon dans le forum Langage
    Réponses: 3
    Dernier message: 11/06/2003, 18h07
  4. Overload
    Par JMF dans le forum Langage
    Réponses: 8
    Dernier message: 18/04/2003, 09h19
  5. [imprecis]Réaliser a^n avec seulement l'opérateur d'addition
    Par Amon dans le forum Algorithmes et structures de données
    Réponses: 18
    Dernier message: 08/11/2002, 22h22

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