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 :

Surcharge d'opérateur pour une classe incrusté dans une autre classe ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur à ses heures perdues
    Inscrit en
    Août 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur à ses heures perdues

    Informations forums :
    Inscription : Août 2011
    Messages : 36
    Par défaut Surcharge d'opérateur pour une classe incrusté dans une autre classe ?
    Bonjour à tous,

    Je suis actuellement en train d'apprendre le C++ sur le livre de Stroustrup. Je suis au chapitre concernant les classes et on me demande de construire une classe Livre dont les membres sont ISBN, l'auteur, le titre, la date de copyright, un membre indiquant si le livre est sorti ou non (d'une bibliothèque par exemple). On nous demande d'écrire des fonctions qui renvoient la valeur de chacun des membres avec une précision concernant l'ISBN qui doit s'écrire suivant ce format n-n-n-x (n peut etre un entier de longueur variable suivant Wikipedia, et x soit une lettre soit un chiffre). Afin de pouvoir le représenter sous ce format j'ai pensé à écrire une classe pour l'ISBN. J'ai également implémenté une classe Date pour représenter la Date dont les détails ne nous intéressent pas pour le problème que je rencontre. Voici un extrait de mon code (un code de débutant) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class ISBN{
     
    public:
        ISBN(int a, int b, int c, char x);
        int get_a() const {return a;}
        int get_b() const {return b;}
        int get_c() const {return c;}
        char get_x() const {return x;}
     
    private:
        int a,b,c;
        char x;
    };
    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
    class Livre{
    public:
        Livre(ISBN isb,string title, string author, Date copyright);
        ISBN get_isb() const {return isb;}
        string get_title() const {return title;}
        string get_author() const {return author;}
        Date get_date() const {return copyright;}
        void borrow(int i) {release = (i==1) ? true : false;}
    private:
        ISBN isb;
        string title;
        string author;
        Date copyright;
        bool release;
    };
    On me demande de surcharger l'opérateur == afin de vérifier si deux livres ont le même ISBN.

    J'ai d'abord fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    bool operator==(const ISBN& isb1, const ISBN& isb2)
    {
        if (isb1.get_a()==isb2.get_a() && isb1.get_b()==isb2.get_b() && isb1.get_c()==isb2.get_c() && isb1.get_x()==isb2.get_x())
            return true;
        else
            return false;
    }
    et ensuite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    bool operator==(const Livre& book1, const Livre& book2)
    {
        if (book1.get_isb()==book2.get_isb())
            return true;
        else
            return false;
    }
    if (book1.get_isb()==book2.get_isb()) compare deux termes de type ISBN, avec la surcharge que j'ai implémenté juste avant cela ne devrait pas poser de problème a priori puisque j'ai défini le test d'égalité de deux variables de type ISBN, non ? A la compilation ma fonction bool operator==(const ISBN& isb1, const ISBN& isb2) ne pose pas de problème mais la suivante si avec ceci comme erreur :
    error: no match for 'operator==' in '((Livre*)book1)->Livre::get_isb() == ((Livre*)book2)->Livre::get_isb()'|

    Des suggestions ?

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 127
    Par défaut
    Bonjour,


    En premier, une petite rectification : il ne s'agit pas d'une classe "incrustée" dans une autre mais simplement une instance d'une classe (ISBN) utilisée dans une autre (Livre) en temps que membre. En objet on parle d'une relation de composition (l'objet ISBN membre de "Livre" est créé et disparaît avec l'objet "Livre").

    Ceci mis à part, je pense qu'il te manque simplement une "forward declaration" de la redéfinition de l'opérateur == pour ISBN.
    Si tu ne l'as déjà fait, tu devrais aussi déclarer et définir un constructeur sans argument pour ISBN et pour prendre de bonnes habitudes également un constructeur de copie, même s'il n'est pas indispensable ici.
    Pourquoi ces constructeur ? par exemple pour que ton constructeur Livre(ISBN ,.....) puisse fonctionner, le premier argument étant un ISBN passé par valeur.

    A mon avis, rajoute cette ligne à la fin de ton fichier isbn.h, ajoute le constructeur simple au moins, et ça va compiler:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool operator==(const ISBN& isb1, const ISBN& isb2);
    Cordialement

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur à ses heures perdues
    Inscrit en
    Août 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur à ses heures perdues

    Informations forums :
    Inscription : Août 2011
    Messages : 36
    Par défaut
    J'ai suivi tes conseils et cela a marché. J'ai crée un constructeur par défaut pour les classes, et j'ai déclaré les fonctions de surcharge comme tu me l'as suggéré et cela passe nickel à la compilation. En revanche, ce que j'ai du mal à comprendre c'est la nécessite de faire une "forward déclaration". Si j'ai défini mon opérateur == pour la classe ISBN, ne puis je pas l'utiliser juste après dans une fonction sans la déclarer au préalable dans l'en tête. (Quand je dis déclarer, je parle du prototype)

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Créer une classe ISBN en me paraît pas justifié.
    Je me serais contenté d'un string.

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 127
    Par défaut
    Bonjour,

    Comme tu ne dis pas dans quels fichiers se trouve chaque bout de code, je ne sais pas exactement te répondre, mais que veux tu dire par :
    Si j'ai défini mon opérateur == pour la classe ISBN, ne puis je pas l'utiliser juste après dans une fonction sans la déclarer au préalable dans l'en tête.
    Si tu défini cet opérateur dans le même source que celui de Livre et AVANT, alors ça doit marcher aussi, sauf si dans un .h quelque chose a besoin de cet opérateur, ou un autre .cpp.

    Par exemple, si tu mets dans cet ordre les lignes suivantes dans Livre.cpp, sans avoir mis la ligne de déclaration, ça marchera aussi, tout est une question d'ordre d'apparition des déclarations.
    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
       Livre::Livre(ISBN isb,string title, string author, Date copyright)
    	{
    	  // blabla ...
    	}
     
     
        bool operator==(const ISBN& isb1, const ISBN& isb2)
        {
          if (isb1.get_a()==isb2.get_a() && isb1.get_b()==isb2.get_b() && isb1.get_c()==isb2.get_c() && isb1.get_x()==isb2.get_x())
            return true;
          else
            return false;
        }
     
        bool operator==(const Livre& book1, const Livre& book2)
        {
          if (book1.get_isb()==book2.get_isb())
            return true;
          else
            return false;
        }
    Mais je te conseille de toujours mettre des forward déclaration dans le fichier .h, ça évite de se soucier justement dans quel ordre on place les implémentations.

    Cordialement

  6. #6
    Membre averti
    Homme Profil pro
    Ingénieur à ses heures perdues
    Inscrit en
    Août 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur à ses heures perdues

    Informations forums :
    Inscription : Août 2011
    Messages : 36
    Par défaut
    Pour l'instant j'ai mis tout mon code sur un seul et même fichier (ce qui n'est pas propre je le reconnais) et j'ai déclaré dans l'ordre que tu as mis c'est à dire :

    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
       Livre::Livre(ISBN isb,string title, string author, Date copyright)
    	{
    	  // blabla ...
    	}
     
     
        bool operator==(const ISBN& isb1, const ISBN& isb2)
        {
          if (isb1.get_a()==isb2.get_a() && isb1.get_b()==isb2.get_b() && isb1.get_c()==isb2.get_c() && isb1.get_x()==isb2.get_x())
            return true;
          else
            return false;
        }
     
        bool operator==(const Livre& book1, const Livre& book2)
        {
          if (book1.get_isb()==book2.get_isb())
            return true;
          else
            return false;
        }
    Mais ce n'est qu'après avoir fait une forward déclaration et crée un constructeur par défaut que l'erreur de compilation ne s'affichait plus. A l'avenir je ferai toujours en sorte de faire une telle déclaration et de mieux organiser mon code. Merci de votre aide

    Sinon si j'ai crée une class ISBN au lieu d'utiliser un string c'est parce qu'un code ISBN a quatre partie n-n-n-x, chacune des parties peut avoir une taille différentes. Il est donc plus judicieux de créer une classe ISBN afin de pouvoir récupérer le premier n du code qui correspond à des zones de langues, de pays. Sur un string cela me parait plus ardu (mais possible ! ). En plus cela m'a permis d'en apprendre plus sur les classes

Discussions similaires

  1. [AJAX] Refresh d'une page incrusté dans une div
    Par noam00 dans le forum jQuery
    Réponses: 0
    Dernier message: 21/05/2015, 11h53
  2. Réponses: 2
    Dernier message: 19/07/2011, 13h57
  3. Réponses: 8
    Dernier message: 05/04/2011, 08h06
  4. Réponses: 7
    Dernier message: 03/12/2008, 15h18
  5. Réponses: 11
    Dernier message: 06/12/2005, 08h23

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