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 :

operator== : problème comparaison d'objets pointés


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 19
    Par défaut operator== : problème comparaison d'objets pointés
    Bonjour,

    Voici un petit bout de code, les explications suivront celui-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class Activity
    {
        int order;
        std::string action;
    public:
        ...
        bool operator==(const Activity &activity) const
        {
            return activity.isOrder(order) && activity.isAction(action);
        };
    }
    En fait, la classe Activity, comme d'autres classes, seront utilisés dans un graphe générique. Il y aura une recherche, finissant par une comparaison, ce qui m'amène pour un type template Vertex à faire comme tel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    template<class Vertex>
    class Graph { ... };
    ...
    template<class Vertex>
    bool Graph<Vertex>::isValid(Vertex v)
    {
        // recherche
        return (v == v2);
    }
    ...
    Graph<int> integerGraph;
    Graph<Activity *> activityGraph;
    Si Vertex = int, je me vois de laisser une comparaison sans pointeur (v == v2).
    Mais si Vertex = Activity*, cette comparaison ne marche pas, car il faudrait alors (*v == *v2) qui, elle, fonctionne.
    J'ai cru pouvoir résoudre le problème en redéfinissant l'opérateur == dans la classe Activity d'une autre manière (déréférencé le pointeur grâce à l'argument) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        bool operator==(const Activity *activity) const
         {
             return activity->isOrder(order) && activity->isAction(action);
         };
    Mais la comparaion (v == v2) échoue.
    C'est indispensable pour moi de trouver une déclaration de l'opérateur == dans la classe Activity qui me permet de garder le format de comparaison (v == v2) lors de la recherche dans la classe Graph.
    J'espères que vous aurez une solution pour moi. Merci d'avance pour votre aide !

  2. #2
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    Salut !

    Je pense qu'il faudrait que tu spécialises la fonction [/code]template<class Vertex> bool Graph<Vertex>::isValid(Vertex v)[/code]
    pour prendre en compte le fait que Vertex puisse représenter un pointeur, c'est à dire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<class Vertex>
    bool Graph<Vertex*>::isValid(Vertex* v)
    {
        // recherche
        return (*v == *v2);
    }
    comme ça, ainsi, si ton Graph contient des pointeurs, alors ce sont les objets pointés qui seront comparés...

    cependant, fait attention, parce que si on veut VRAIMENT que ton Graphe contienne des pointeurs, (c'est à dire, dans ce cas, que ce soient les pointeurs et non les valeurs qui devraient être égales) cela posera sûrement problème

    Il y a peut-être une erreur de modélisation quelque part ^^
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  3. #3
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 19
    Par défaut
    J'ai du mal à comprendre ta solution..
    Si je fais Graph<Activity *> myGraph, alors, dans ton cas, Vertex sera égal à Activity**. Si je ne me trompes pas, ce n'est pas vraiment ce que je souhaites. Peut-être ais-je manqué une subtilité.
    Sinon, si on suppose qu'on ne veut pas que mon graphe contienne vraiment des pointeurs, est-ce qu'il existe une solution plus.. radicale ?

  4. #4
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    alors, non

    il s'agit de spécialisation, c'est à dire que quand tu appelleras
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool Grap<Activity*>::isValid(Activity*);
    il recherchera les fonctions template correspondante, la première sera :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template<class Vertex> bool Graph<Vertex>::isValid(Vertex);
    au quel cas, Vertex se voit être égale à Activity*
    la seconde est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template<class Vertex> bool Graph<Vertex*>::isValid(Vertex*);
    Auquel cas, Vertex se vois être égal à Activity, le * étant sépcifé explicitement

    Le second cas est "plus précis", plus spécialisé...
    de même, si par exemple tu faisais une spécialisation pour les vecteurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template<class Vertex> bool Graph< vector<Vertex> >::isValid(vector<Vertex>);
    ou pour d'autres types
    c'est la signature la plus spécialisée qui l'emporte...

    je pense que tu as compris ?
    (exemple, une spécialisation pour les pointeurs const :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template<class Vertex> bool Graph<const Vertex*>::isValid(const Vertex*);
    comme il y en a deux pour les pointeurs, si tu utilises un Graph<Activity*> c'est celle en Vertex* qui sera utilisée (on ne peut pas utiliser const Vertex*) et si tu utilises un Graph<const Activity*> c'est celle en const Vertex* qui le sera, car plus spécialisée (dans le premier cas (général) Vertex représente const Activity*, dans le second (pointeurs) il représente const Activity, et dans le dernier, uniquement Activity)
    J'espère que c'est un peu plus clair ?
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  5. #5
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 19
    Par défaut
    Effectivement, mais je voudrais éviter la spécialisation, car je ne traite que des Activity* tout au long de mon algorithme, pour un des graphes. Mais pour d'autres, j'utilises des strings ou des ints..
    Je voudrais vraiment arriver à un résultat du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Activity *one = new Activity(1);
    Activity *two = new Activity(1);
     
    if (one == two)
        cout << "ok" << endl;
    else
        cout << "nok << endl;
    Je voudrais donc overloadé l'opérateur == avec un paramètre autre que const Activity &activity (car dans ce cas, il faut faire une comparaison *one == *two pour que ça fonctionne) tel que je puisses faire une comparaison one == two.
    Je souhaites vraiment avoir un même algorithme capable de s'adapter à des objets de tout type. N'y a-t-il vraiment pas une solution autre que la spécialisation ?

  6. #6
    Membre émérite Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Par défaut
    Comme il est difficile de passer par la spécialisation, ainsi que le démontre fort justement Swoög ci-dessus, je pense qu'il faudrait essayer de passer par un adaptateur. L'idée serait de créer une classe légère te permettant de traiter un pointeur comme un type non pointé dans les cas qui t'intéressent.

    Quelque chose comme ça, donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    template< class T >
    class Unptr
    {
      public : 
        Unptr( T* ptr ) : m_ptr( ptr ) {}
        const T* get() const { return m_ptr; }
        bool operator ==( const Unptr< T >& rhs ) { return *m_ptr == * rhs.get(); }
       [etc...]
     
      private : 
        T* m_ptr;
    };
    Moyennant quoi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
      int* p1 = new int( 5 );
      int* p2 = new int( 5 );
     
      Unptr< int > up1( p1 );
      Unptr< int > up2( p2 );
     
      bool eq =  up1 == up2;
      cout << eq << endl;
      [delete...]
    se comporte comme il faut.
    Si contruire des Graph< Unptr< Activity > > au lieu des Graph< Activity* > est envisageable, ce type d'approche peut peut-être aider.

  7. #7
    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
    Pourquoi ne pas surcharger l'operateur == avec les 2 pointeurs en argument ?
    De toute manière, il ne vaudrait mieux pas que operator== soit défini dans la classe à moins qu'il ait absolument besoin d'un élément auquel on ne pourrait pas avoir accès. Il peut même être défini en fonction d'une fonction membre de la classe.

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

Discussions similaires

  1. Problème comparaison objets avec equals
    Par belkasmi dans le forum Langage
    Réponses: 8
    Dernier message: 01/08/2007, 17h39
  2. Problème de procédure objet : Migration de TForm vers TFrame
    Par rvzip64 dans le forum Composants VCL
    Réponses: 3
    Dernier message: 13/06/2005, 13h44
  3. Probléme collection d'objets
    Par Contrec dans le forum MFC
    Réponses: 1
    Dernier message: 14/04/2005, 10h08
  4. [FLASH MX] Problème avec l'objet Date
    Par n_tony dans le forum Flash
    Réponses: 13
    Dernier message: 22/03/2005, 13h44

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