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 :

Petit probléme de surcharge d'opérateur .


Sujet :

C++

  1. #1
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut Petit probléme de surcharge d'opérateur .
    Re-Bonjour .
    J'ai deja surchargé des opérateur avant ... et la je ne comprend pas ce qu'il me manque :

    je cherche a tester si un objet t est présent ou non dans un vector avant de l'ajouter . pour cela je fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if ( std::find(Trans.begin(), Trans.end(),t ) != Trans.end() )  blabla
    J'ai ensuite surchargé les opérateur == et != de cette facons :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     bool operator == (const cTransition & )const;
     bool operator != (const cTransition  &)const ;
     
     
    bool cTransition::operator == (const cTransition & t) const
    {
        return ( (ini == t.ini) && (fin == t.fin) && (lettre == t.lettre ) ) ;
    }    
    bool cTransition::operator != (const cTransition & t) const
    {
        return ( (ini == t.ini) || (fin == t.fin) || (lettre == t.lettre ) ) ;
    }
    Mais rien n'y fait , meme aprés voir ajouté 2 fois le meme objet t, je ne passe jamasi dans ce qu'il y a aprés le if ... :/
    J'ai testé une comparaison simple du style ( t == Trans[i] ), pas de probléme ca marche ca par contre .
    J'ai meme rajouté tout les opérateur ( > >= < <= ) il semble que std::find ne fasse appel a aucun de mes opérateur redéfinis

    edit : j'ai oublié de dire comment je déclarait tout ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     cTransition * t = new cTransition() ;
    std::vector< cTransition *> Trans ;

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2003
    Messages : 65
    Points : 73
    Points
    73
    Par défaut
    D'abord, il me semble qu'il y a une erreur dans ton opérateur != qui devrait plutôt être ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bool cTransition::operator != (const cTransition & t) const 
    { 
        return ( (ini != t.ini) || (fin != t.fin) || (lettre != t.lettre ) ) ; 
    }
    Mais ce n'est pas la source du problème (d'ailleurs, je crois que find utilise seulement ==). Ton std::vector< cTransition *> contient des pointeurs. Même deux objets identiques n'auront pas la même adresse, alors find ne trouve pas car il compare des pointeurs. En effet, puisqu'il s'agit de pointeurs, ta fonction membre cTransition::operator==() n'est pas appelée.

  3. #3
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Je crois que dans ton cas tu es obligé d'utiliser un objet fonction et l'algo find_if:

    http://www.developpez.net/forums/viewtopic.php?t=319113

  4. #4
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Axile : oui une erreur dans mon opérateur ... j'ai fait ca trop vite merci .
    C'est bien ce que je pensait ... probleme de pointeur :/

    Moldavi : Un objet fonction c'est un foncteur c'est ca ?
    J'ai survolé le lien que tu ma donné, je m'y pencherais plus en détail ce matin ... hum il doit bien y avor une solution plus "jolie" .
    Enfin merci

  5. #5
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Si tu en trouve une ça m'intéresse. Le problème c'est qu'apparemment l'algo find ne travaille que sur des valeurs simples comme des int, des float, etc...

    A partir du moment ou ton objet se complexifie (type personnalisé), tu dois aider l'algo afin de lui dire comment comparer les valeurs de ton type. D'ou le foncteur (objet fonction).

    C'est le niveau d'analyse que j'en ai, mais je peux me tromper.

  6. #6
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Bah, ca se tient tout ca Il me reste plus qu'a regarder ou se place le foncteur dans le corps de la fonction find : find_if ect ^^

  7. #7
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Hum, je veint de me fire un foncteur vite fait :

    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
     
    struct SortByVal
    {
     
       bool operator()( const Transition & t1, const Transition & t2 ) const
       {
          if ( t1.ini < t2.ini )
    	 return true ;
          if ( t1.ini == t2.ini)
          {
    	   if ( t1.lettre < t2.lettre )
    		   return true ;
    	   if ( t1.lettre == t2.lettre )
    	   {
    		   if ( t1.fin < t2.fin )
    			   return true ;
    	   }
       }
       return false ;
       }
    };
    Mais bon, a part réaliser un tri , je ne vois pas comment je vais m'en servir ! ( j'ai regardé dans la doc, find / find_if ne prenne pas en argument un foncteur de toute facons . )
    Faut-il que je crée une fonction de recherche moi meme ?
    N'y a til rien de plus simple ?
    Ou alors la solution la + simple n'est-elle pas de me passer de pointeur et d'utiliser des cTransition tout court ?
    a bon entendeur ^^

  8. #8
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Tu as mal lu le lien que je t'ai donné. Moi aussi je n'y comprenais rien et maintenant ça va.

    Lis bien les explications. Le principe c'est d'avoir une classe supplémentaire dont tu surcharges l'opérateur ().

    Pour tester une classe avec l'ensemble de ton vector, tu construit la classe ci-dessus avec l'objet à comparer. Tu passes à find_if la classe temporaire fraichement construite avec l'opérator () qui va appeler ta fonction de comparaison (qui doit retourner true ou false).

    Tu peux aussi effectivement utiliser une fonction dédiée, mais tu tout dépend comment tu organises ton programme.

  9. #9
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Hum, oki doki, je vais donc essayer comme ca en rentrant chez moi !

    On fait une deuxiéme classe .

    On initialise juste avant d'apeller find_if, une instance de cette classe, en affectant a ses var menbre les valeur de l'objet que l'on veut réelement tester .
    Ensuite on apelle find_if sur cet objet nouvellement créer, tout en oublint pas de surcharger l'opérateur ()
    J'ai bon :p ?
    merci en tout cas !

  10. #10
    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
    Points : 15 920
    Points
    15 920
    Par défaut
    Une solution jolie serait boost::lambda, avec lequel on pourrait écrire ce genre de choses (si je ne me trompe pas) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find_if(v.begin(), v.end(), *_1 == t);
    Sinon, tu peux écrire des foncteurs "intermédiaires" qui vont s'occuper de déréférencer le pointeur et d'envoyer la valeur obtenue à un autre foncteur, qui fera lui le vrai job.

  11. #11
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Je vais de ce pas consulter la doc de boost::lambda et sinon je mettrai en place la solution du dessus qui semble marcher
    merchi

  12. #12
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    j'ai include boost/lambda/lambda.hpp ( je pense que c'est le bon header ... )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     if ( std::find_if(Trans.begin(), Trans.end(),*_1 == t ) != Trans.end() ) 
    			  std::cout << "test" ;
    ne compile pas, il m'envoie balader car il ne reconnait pas _1

    edit: c'est vrai que ca y ressemble dans la doc de la lib

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sort(vp.begin(), vp.end(), *_1 > *_2);
    y doit y avoir moyen d'y arriver

  13. #13
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Je patague un peu la ... que ce soit avec une methode ou l'autre je n'arrive pas a en tirer qquchose ... je ne sais pas pourquoi j'ai du mal a voir ce que je fait :/

  14. #14
    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
    Points : 15 920
    Points
    15 920
    Par défaut
    Montre nous ce que tu as fait, et explique nous plus précisément sur quoi tu bloques

  15. #15
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Et bien n'ayant pas beaucoup de psites sur boost::lambda, j'ai mis cette option de coté .

    Je me suis donc orienté vers la création dune classe qui me servira pour effectuer la comparaison . ( comme suggéré + haut )

    Dans le code, ca donne ca en gros :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    cTransition * t = new cTransition() ;
      t->ini = iniT;
    		  t->fin = finT ;
    		  t->lettre = lettreT;
     
    		  cTransComp  TComp ;
    		  TComp.ini = t->ini;
    		  TComp.fin = t->fin;
    		  TComp.lettre = t->lettre ; 
     
             if ( std::find(Trans.begin(), Trans.end(), TComp ) != Trans.end() ) ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    bool cTransComp::operator ()(const cTransComp & t1) const 
    {
       return true ;
    }
    J'ai mis return true, juste pour tester .

    error C2679: binary '==' : no operator found which takes a right-hand operand of type 'const cTransComp' (or there is no acceptable conversion)
    ceci était l'erreur

    Sinon si je rempalce ca par find_if j'ai ca comme erreur :

    c:\Microsoft Visual Studio .NET 2003\Vc7\include\algorithm(64): error C2664: 'bool cTransComp::operator ()(const cTransComp &) const' : cannot convert parameter 1 from 'std::allocator<_Ty>::value_type' to 'const cTransComp &'
    with
    [
    _Ty=cTransition *
    ]
    voili voilou

  16. #16
    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
    Points : 15 920
    Points
    15 920
    Par défaut
    1ere erreur : find prend en 3eme paramètre l'élément à comparer directement, càd du même type que ce que tu stockes. Il faut donc bien find_if dans ton cas, qui compare non pas une valeur directement mais passe par un prédicat.

    2eme erreur : tu prends en paramètres dans ton foncteur des cTransition alors que tu stockes des cTransition*

    Pour le foncteur tu t'y prends un peu mal :

    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
    struct cTransComp
    {
        cTransComp(const cTransition& t) : Trans(t) {}
     
        bool operator ()(const cTransition* t) const
        {
            return *t == Trans; // ou alors n'importe quel calcul adapté à ton problème
        }
     
    private :
     
        const cTransition& Trans;
    };
     
    cTransition t(...);
    find_if(Trans.begin(), Trans.end(), cTransComp(t));
    On pourrait envisager une version plus générique du foncteur de déréférencement, qui prendrait n'importe quel type et pourrait lui appliquer n'importe quel autre foncteur, mais pour l'instant ce sera déjà pas mal

  17. #17
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    find_if(Trans.begin(), Trans.end(), cTransComp(t));
    Ca il risque de ne pas aimer car t est un pointeur ...

  18. #18
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Merci merci, je suis arrivé a mes fins C'est pas trés jojo , mais ca fonctionne ... alors on fra avec

  19. #19
    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
    Points : 15 920
    Points
    15 920
    Par défaut
    Ca il risque de ne pas aimer car t est un pointeur ...
    Il n'y à qu'à le déréférencer pour le passer au foncteur, ou modifier le foncteur pour qu'il prenne un pointeur. Bref il faut bien sûr que tu adaptes un minimum mon code à tes besoin.

    C'est pas trés jojo , mais ca fonctionne ... alors on fra avec
    Pourquoi c'est pas jojo ?

    En ce qui concerne boost, ceci compile et fonctionne très bien :

    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
    #include <algorithm>
    #include <iostream>
    #include <vector>
    #include <boost/lambda/lambda.hpp>
     
    using namespace boost;
    using namespace lambda;
    using namespace std;
     
    int main()
    {
        vector<int*> v;
        v.push_back(new int(1));
        v.push_back(new int(2));
        v.push_back(new int(3));
        v.push_back(new int(4));
     
        cout << **find_if(v.begin(), v.end(), *_1 == 2) << endl;
     
        return 0;
    }

  20. #20
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Il n'y à qu'à le déréférencer pour le passer au foncteur, ou modifier le foncteur pour qu'il prenne un pointeur. Bref il faut bien sûr que tu adaptes un minimum mon code à tes besoin.
    Cela va sans dire ce n'était en rien une critique

    Pourquoi c'est pas jojo ?
    Je parle de la facons dont je l'ai modifié pour que ca marche ^^ pas de ton code initial

    Concernant boost, je testerais quand j'aurais le temps .
    Juste une question :

    le *_1 == 2 , ca va apeller l'opérateur "==" de la classe en cours ?

    Si oui, c'est sympa :p si non ... ca risque de pas etre jojo pour effectuer des test sur plusieurs variable meneber d'une classe non?[/quote]

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

Discussions similaires

  1. Problème de surcharge d'opérateur flux avec pointeur
    Par eleve_prog dans le forum Débuter
    Réponses: 4
    Dernier message: 18/04/2011, 18h41
  2. problème au surcharge d'opérateur =
    Par zougagh dans le forum C++
    Réponses: 12
    Dernier message: 28/06/2010, 17h29
  3. Problème de surcharge d'opérateur std::cout
    Par Nyko17 dans le forum C++
    Réponses: 14
    Dernier message: 28/04/2008, 13h01
  4. Réponses: 7
    Dernier message: 02/12/2007, 21h43
  5. Problème de surcharge d'opérateurs
    Par Hell dans le forum C++
    Réponses: 17
    Dernier message: 17/01/2005, 16h01

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