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 :

Utiliser une surcharge d'operateur dans une autre classe du projet ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2012
    Messages : 15
    Par défaut Utiliser une surcharge d'operateur dans une autre classe du projet ?
    Bonjour à tous ,

    Mon programme est assez simple, je crée des objets 'Livre' que j'insère dans un objet 'VecteurTrie', dans lequel j'essaye de les trier par nom, puis par auteurs, pour ensuite les afficher.

    Voici mon code :

    surcharge des operateurs de comparaison dans Livre.cpp:
    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
    22
    23
    24
    25
    26
    27
    28
    29
    int Livre::compare(Livre l)
    {   
        if(strcmp(titre,l.titre) < 0) return -1;
        else if(strcmp(titre,l.titre) > 0) return 1;
        else
        {
           for(int i=0; i<MAX; i++)
           {
             if(strcmp((auteurs[i]->Nom),(l.auteurs[i]->Nom))== -1) return -1;
             if(strcmp((auteurs[i]->Nom),(l.auteurs[i]->Nom))== 1) return 1;
           }
           return 0; // si titre et auteurs identiques
        }
    }
     
    int Livre::operator<(const Livre& l)
    {   
        return compare(l)== -1;
    }
     
    int Livre::operator==(const Livre& l)
    {   
        return compare(l)== 0;  
    }
     
    int Livre::operator>(const Livre& l)
    {   
        return compare(l)== 1;
    }

    Ma classe VecteurTrie.cpp
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
     
    template <class type> VecteurTrie<type>::VecteurTrie()
    {
        tab = new type[10];
        pTop = tab;
        nbrElem=0;                       
    }
     
    template <class type> VecteurTrie<type>::VecteurTrie(int ne)
    {   
        if(ne < 11)
        {
            nbrElem = ne;
        }
        else{ nbrElem = 10; }
     
        tab = new type[nbrElem];
        pTop=tab;
    }
     
    template <class type> VecteurTrie<type>::VecteurTrie(const VecteurTrie<type> &v)
    {
        nbrElem=v.nbrElem;
        tab=new type[nbrElem];
        tab=v.tab;
        pTop=v.pTop;     
    }
     
    // fonction membre
     
    template <class type> void VecteurTrie<type>::insert(type a)
    {
        if(nbrElem < 10)
        {
            *pTop = a;
            pTop++;
     
            int mmin;
            type temp;
     
            // le tri ne fonctionne pas avec les objets livres... 
     
            for (int i=0; i<nbrElem-1; i++)
            {
                mmin = i;
                for (int j=i+1; j<nbrElem; j++)
                {
                    if (tab[j] < tab[mmin])
                    {
                        mmin = j;
                    }
     
                    if (mmin != i)
                    {
                        temp = tab[i];
                        tab[i] = tab[mmin];
                        tab[mmin] = temp;
                    }
                }    
            }
        }
        else{ throw VectorFullException("Erreur: Le vecteur est plein."); }
    }
     
    template <class type> void VecteurTrie<type>::removeElem(type a)
    {
        if(nbrElem > 0)
        {
            int cpt = 0;
            for(int i=0; i<nbrElem; i++)
            {
                cpt++;
                if(a==tab[i])
                {
                    for(int j=cpt-1; j<nbrElem-1; j++)
                    {
                        tab[j]=tab[j+1];
                    }
                    nbrElem--;
                    cout << "Element retire : " << a << endl << endl;
                }
                else { cout << "Error: Element inexistant." << endl << endl; }
            }
        }
        else { cout << "Error: Vecteur vide." << endl << endl; }
    }
     
    template <class type> void VecteurTrie<type>::displayy(void)
    {
        if (nbrElem == 0)
        {
            cout << "Vecteur vide" <<endl;
        }
        else
        {
            for(type *i=pTop; i!=tab;)
            {
                cout << *--i << "    ";
            }
            cout << endl;
        }
    }
     
    // class destructor
    template <class type> VecteurTrie<type>::~VecteurTrie()
    {
    	delete[] tab;
    }
     
    template class VecteurTrie<int>;
    template class VecteurTrie<Livre>;
    Ma classe VecteurTrie.h (au cas où):
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #ifndef VECTEURTRIE_H
    #define VECTEURTRIE_H
     
    #include "Vecteur.h"
    #include "vectorfullexception.h"
    #include "livre.h"
     
    /*
     * No description
     */
    template <class type> class VecteurIter;
     
    template <class type> class VecteurTrie : public Vecteur
    {
        protected:
            type *tab;
            type *pTop;
            int nbrElem;
     
        public:
            VecteurTrie();
            VecteurTrie(int nb);
            VecteurTrie(const VecteurTrie<type> &v);
            ~VecteurTrie();
     
            type& operator[] (int i) {return *(tab+i);}
    	    bool operator<(const VecteurTrie& v) const {return tab < v.tab;}
     
            void insert(type a);
            void removeElem(type a);
            void displayy();
     
            friend class VecteurIter<type>;
    };
     
    #endif // VECTEURTRIE_H

    Ma classe de test main.cpp
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #include <cstdlib>
    #include <iostream>
    #include <stream.h>
     
    #include "Livre.h"
    #include "Vecteur.h"
    #include "VecteurTrie.h"
     
    using namespace std;
     
    int main(int argc, char *argv[])
    {   
        Livre p;
        int elem;
        int nbelem;
     
        VecteurTrie<Livre> vtl(3);    // je décide qu'il y a trois elems
     
        cout << "Testons maintenant avec des livres." << endl;
        cout << endl;
     
           // je crée les livres:
        char *aut[3]={"Tintin","Spirou","Haddock"};
     
        Livre p0 ("Coucou je suis Pierre Bolle", 3, "977-2-87777-007-1", aut, 3, 45,"Science-fiction");
        Livre p1 ("Coucou ", 3, "977-2-87799-007-2", aut, 3, 55,"Germain");
        Livre p2 ("Coucou je suis ", 3, "977-2-87788-007-3", aut, 3, 65,"Fantaisie");
     
        vtl.insert(p0);
        vtl.insert(p1);
        vtl.insert(p2);
     
        //cout << "Vecteur de trois livres:" << endl << endl;
        //vtl.displayy();
     
     
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    Le problème est qu'au moment de l'exécution, mon programme s'arrête crash, sans donner le moindre message d'erreur.
    Je précise que si je teste ma surcharge directement dans la classe main, elle fonctionne très bien.
    Si je teste mon tri avec des entiers, cela fonctionne très bien également.

    Je débute en c++ et j'ai bien sur bien lu mon cours ainsi que la FAQ du forum avant de poster

    Merci d'avance pour votre aide.

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Je le dis tout de suite, je n'ai pas lu tout le code, mais:

    Plutôt que d'utiliser des chaine de caractères "C style", tu devrais utiliser la classe std::string, qui est beaucoup plus sécurisante à l'utilisation

    Je ne sais pas ce que c'est que ta classe Vecteur, mais, plutôt que d'utiliser une classe personnelle, tu devrais utiliser la classe std::vector, qui, encore une fois, est surement plus sécurisante que n'importe quelle implémentation similaire "a mano".

    Un tableau trié (ou n'importe quelle collection triée) ne devrait jamais hériter de tableau (ou de la collection équivalente non triée) car la notion de tri impose des préconditions incompatibles avec la notion des collections non triées.

    En effet, la dernière chose à vérifier pour déterminer si l'on peut procéder à un héritage est de s'assurer que les règles de la programmation par contrat soient respectées.

    Or, dans un héritage publique, ces règles imposent que les préconditions ne peuvent pas être plus restrictives dans le type dérivé que dans le type de base.

    Et, comme la précondition d'une collection triée est ... qu'elle soit triée avant toute manipulation, et que cette précondition n'existe pas dans une collection non triée, les préconditions sont plus importantes dans la collection triée.

    La règle n'est donc pas respectée et l'héritage doit par conséquent être abandonné

    Ceci étant dit, comme VecteurTrie hérite de Vecteur, on peut décemment estimer que ta classe Vecteur s'occupe déjà de gérer elle-même la mémoire pour les différents éléments qu'elle doit manipuler.

    Dés lors, pourquoi rajouter des membres comme tab et nbrElem dans ton tableau trié n'est-ce pas, typiquement, des données qui se retrouvent dans n'importe quel vecteur non trié
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2012
    Messages : 15
    Par défaut
    Bonjour à tous:

    Citation Envoyé par koala01 Voir le message
    Je le dis tout de suite, je n'ai pas lu tout le code, mais:

    Plutôt que d'utiliser des chaine de caractères "C style", tu devrais utiliser la classe std::string, qui est beaucoup plus sécurisante à l'utilisation

    Je ne sais pas ce que c'est que ta classe Vecteur, mais, plutôt que d'utiliser une classe personnelle, tu devrais utiliser la classe std::vector, qui, encore une fois, est surement plus sécurisante que n'importe quelle implémentation similaire "a mano".
    Je ne sais pas le professeur a utilisé des déclarations de chaine/vecteur/... "c-style" dans tout son cours et ne nous a pas demandé de faire autrement.

    Je suis débutant en c++ et l'énoncé de mon travail me demande de créer une classe VecteurTrie template, dérivant d'une classe Vecteur (qui ne connaît
    pas la notion de tri) encapsulant un tableau dynamique.

    Le niveau sécuritaire n'a pas beaucoup d'importance, je ne fais que suivre l'énoncé.

    Citation Envoyé par Ehonn
    Écriture du programme principal : création d'un std::vector de livres, utilisation de std::sort sur le vector avec le foncteur qui va bien selon le tri voulu (la FAQ donne un exemple qui fait exactement ça ).
    Je regarde à celà attentivement et j'essaye actuellement de l'appliquer, mais comme je n'ai jamais appris autrement qu'en "c-style" à l'école, la lecture n'est pas aisée

    Citation Envoyé par cob59
    Est-ce que ton type Livre implémente ces méthodes-ci ? C'est indispensable, puisque ton vecteur gère ses éléments par valeur.
    Que voulez-vous dire par là svp ? Je pense que ceci touche à mon problème puisque mon tri s'effectue correctement pour les entiers.

    Merci pour l'intérêt que vous portez à mon problème ,
    Evijn.

  4. #4
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut
    Citation Envoyé par Evijn Voir le message
    Que voulez-vous dire par là svp ? Je pense que ceci touche à mon problème puisque mon tri s'effectue correctement pour les entiers.
    Pour que ton vecteur puisse trier des objets Livre, il a besoin de savoir comment les copier, les affecter, etc. Il y a donc 2 solutions :

    Soit tu ne redéfinis AUCUNE des 4 méthodes citées dans la FAQ, auquel cas ta classe Livre se comportera implicitement comme une structure C classique.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Livre() : attr1(), attr2() {}
    Livre(const Livre& other) : attr1(other.attr1), attr2(other.attr2) {}
    Livre& operator=(const Livre& other) { attr1=other.attr1; attr2=other.attr2; }
    ~Livre() {}
    Soit tu redéfinis l'une d'entre elles, auquel cas tu dois impérativement redéfinir les 3 autres. Sinon elles garderont implicitement une implémentation vide (ce n'est pas ce qu'on veut, notamment pour le constructeur par recopie et l'affectation) avec pour conséquence --entre autre -- de faire échouer le tri.

    A côté de ça, il peut aussi être intéressant (voire obligatoire, mais pas dans ton cas) d'implémenter le swap : http://cpp.developpez.com/faq/cpp/?p...orme_canonique

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2012
    Messages : 15
    Par défaut
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    // Constructeur par défaut
    Livre::Livre() : DocumentPapier()
    {             
       n=0;
       prix=0;
       ISBN=0;
       nombreAuteurs=0;
       genre=0;
    }
     
    // constructeur d'initialisation
    Livre::Livre(char *title)
    {
       titre = new char [strlen(title)+1];
       strcpy(titre,title);
     
       n=0; 
       prix=0; 
       ISBN=0; 
       nombreAuteurs=0; 
       genre=0;
     
       for(int i=0; i<MAX; i++)                 
       {
           auteurs[i]=0;
       }
    }
     
    // constructeur de copie
    Livre::Livre(const Livre &l) : DocumentPapier(l)
    {
        n= l.n;
        ISBN = new char [strlen(l.ISBN)];
        strcpy(ISBN,l.ISBN);
        prix=l.prix;
        genre = new char [strlen(l.genre)];
        genre=l.genre;
    }
     
    // Constructeur d'initialisation 2
    Livre::Livre(char *tit, int nb, char *isbn, char *autor[], int nbrAuteurs,
           float p, char *g) : DocumentPapier(autor, nbrAuteurs, tit)
    {
        titre = new char [strlen(tit)+1];
        strcpy(titre,tit);
        n=nb; 
        if (n<0) 
        {
            throw ErrNbExemplaire();
        }
     
        ISBN = new char [strlen(isbn)+1];
        strcpy(ISBN,isbn);
        if (strlen(ISBN) != 17*(sizeof(char))) 
        {
            throw ErrISBN();
        }
        nombreAuteurs=nbrAuteurs;
        Auteur *auteur[nombreAuteurs];
        for (int i=0; i<nombreAuteurs; i++)
        {
           auteurs[i]= new Auteur;
           (auteurs[i]->Nom)=autor[i];        
        }
        PrixAvecTVA pp(p);
        prix=pp.getPrix();
        if (prix<=0) 
        {
            throw ErrPrix();
        }
        genre=g;
    }
    Je pense avoir déjà fait ça correctement


    EDIT: j'ai oublié le destructeur

  6. #6
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut
    Et l'opérateur d'affectation ?

  7. #7
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Bonjour

    Il y a pas mal d'erreur dans ce code. Mis à part une dimension pédagogique ou d'approfondissement, en C++, on utilise std::string (à la place des tableaux de char) et std::vector (à la place d'une classe personnelle buguée).

    Pour tracer des erreurs qui provoquent l'arrêt du programme, je te conseille d'utiliser un débuggeur (comme GDB).
    Pour tracer des erreurs plus "silencieuses", je te conseille un outil comme valgrind qui pourra détecter les fuites mémoire et les utilisations de variations non initialisées.

    Citation Envoyé par Evijn Voir le message
    Mon programme est assez simple, je crée des objets 'Livre' que j'insère dans un objet 'VecteurTrie', dans lequel j'essaye de les trier par nom, puis par auteurs, pour ensuite les afficher.
    Ton programme est compliqué ^^
    Il devrait ressembler à ceci :
    - Création de la classe livre qui contient des std::string pour l'auteur, le titre, ISBN, la catégorie, ...
    - Création de deux foncteurs qui permettent de comparer deux livres selon le nom / l'auteur
    - Écriture du programme principal : création d'un std::vector de livres, utilisation de std::sort sur le vector avec le foncteur qui va bien selon le tri voulu (la FAQ donne un exemple qui fait exactement ça ).

    --- --- ---

    Edit : "grillé". J'avais pas vu pour l'héritage... FAQ C++ - Héritage - FAQ C++ - Héritage, LSP

  8. #8
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut
    Est-ce que ton type Livre implémente ces méthodes-ci ?
    C'est indispensable, puisque ton vecteur gère ses éléments par valeur.

Discussions similaires

  1. Réponses: 1
    Dernier message: 26/12/2010, 21h20
  2. Réponses: 4
    Dernier message: 03/04/2010, 12h05
  3. Ce qui est dans une table mais pas dans l'autre !
    Par youyoule dans le forum Requêtes
    Réponses: 4
    Dernier message: 30/12/2007, 12h57
  4. insertion dans une table puis update dans une autre table
    Par uptoditime dans le forum VBA Access
    Réponses: 5
    Dernier message: 10/10/2007, 18h08
  5. Recherche de valeur dans une feuille et affichage dans une autre
    Par Zebulon777 dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 15/05/2007, 09h40

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