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 :

Gestion d'une bibliothèque


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Mai 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 6
    Points : 1
    Points
    1
    Par défaut Gestion d'une bibliothèque
    bonjour tout le monde, je voudrais réaliser des classes, liveres et emprunteurs sous visual c++, est-ce que quelqu'un peut m'aider?
    merci

  2. #2
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    Bonjour,

    kelkin peut surement t'aider, il vient sur le forum tout les jours, mais il faut lui poser tes questions en Français et en détaillant les points qui te pose des problèmes.

  3. #3
    Membre éprouvé
    Avatar de maxim_um
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    895
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 895
    Points : 1 018
    Points
    1 018
    Par défaut
    Le pire c'est qu'il existe vraiment sur le forum

  4. #4
    Nouveau Candidat au Club
    Inscrit en
    Mai 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Lucien63 Voir le message
    Bonjour,

    kelkin peut surement t'aider, il vient sur le forum tout les jours, mais il faut lui poser tes questions en Français et en détaillant les points qui te pose des problèmes.
    donc tu peut m'aider?? (membre confirmé, juillet 2005 )

  5. #5
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    On peut t'aider, mais pas faire le travail à ta place.

    Il faut que tu nous expliques quel est ton problème, sur quoi tu bloques, avec le code qui pose problème. Là, c'est beaucoup trop vague.

  6. #6
    Nouveau Candidat au Club
    Inscrit en
    Mai 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 6
    Points : 1
    Points
    1
    Par défaut ques
    alors, j'ai deux classes (livre, et client), tout d'abord je voudrais savoir est-ce-que je dois ajouter des autres classes ou ça suffit??

  7. #7
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par hamady's Voir le message
    alors, j'ai deux classes (livre, et client), tout d'abord je voudrais savoir est-ce-que je dois ajouter des autres classes ou ça suffit??
    Et bien je dirais ça dépend... de tes classes livre et client, mais comme on ne les connait pas, on ne peut pas te répondre...
    Il faudrait que tu donne un peu plus d'explication...

  8. #8
    Nouveau Candidat au Club
    Inscrit en
    Mai 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 6
    Points : 1
    Points
    1
    Par défaut error C2065: 'nouvversion'*: identificateur non déclaré
    salut je vien de terminer la classe livre de mon projet:,
    j'ai un petit problème avec ( error C2065: 'nouvversion'*: identificateur non déclaré)
    et voila l'en-tete
    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
    class livre 
    {
    private:
    	char *nomlivre;
    	char *auteur;
    	int version;
    public:
    	livre();//const par defaut 
    	livre(char *nouvnom , char *nouvauteur , int version);
    	~livre(void);
    	char *obtenirnom();
    	char *obtenirauteur();
    	int  obtenirversion();
    	//modification 
    	void modifiernom(char *nouvnom);
    	void modifierauteur(char *nouvauteur);
    	void modifierversion(int nouvversion);
    	void modifier (char *nouvnom , char *nouvauteur, int nouvversion);
    	//affichage 
    	void afficher() const ;
    };
    et voila 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
    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
     
    // pro.cpp*: définit le point d'entrée pour l'application console.
    //
     
    #include "stdafx.h"
    #include "stdafx.h"
    #include "livre.h"
    #include<iostream>
    #include<string.h>
    #include<conio.h>
     
    livre::livre()
    {
    	nomlivre = new char('\0');
    	auteur = new char('\0');
    	version = 0;
    }
    livre::livre(char *nouvnom, char *nouvauteur, int version)
    {
    	nomlivre = new char[strlen(nouvnom)+1];
    	strcpy(nomlivre, nouvnom);
    	auteur = new char[strlen(nouvauteur)+1];
    	strcpy(auteur, nouvauteur);
    	version =   nouvversion ;
    }
    livre::~livre()
    {
    	delete[] nomlivre;
    	delete[] auteur;
    }
    char *livre::obtenirnom()
    {
    	return nomlivre;
    }
    char *livre::obtenirauteur()
    {
    	return auteur;
    }
    int livre::obtenirversion()
    {
    	return version;
    }
    void livre::modifiernom(char *nouvnom)
    {
    	delete[] nomlivre;
    	nomlivre = new char[ strlen (nouvnom)+1];
    	strcpy (nomlivre, nouvnom);
    }
    	void livre::modifierauteur(char *nouvauteur)
    	{
        delete[] auteur;
    	auteur= new char[ strlen (nouvauteur)+1];
    	strcpy (auteur, nouvauteur);
    }
    	void livre::modifierversion( int nouvversion)
    	{
    		version = nouvversion;
    	}
     
     
    		void livre::modifier(char *nouvnom, char *nouvauteur, int nouvversion)
    			{
    delete[] nomlivre;
    	nomlivre = new char[ strlen (nouvnom)+1];
    	strcpy (nomlivre, nouvnom);
     
    	delete[] auteur;
    	auteur = new char [ strlen (nouvauteur)+1];
    	strcpy (auteur, nouvauteur);
    	version =   nouvversion;
    }
    	void livre::afficher() const
    	{
    		std::cout<<"("<<nomlivre<<","<<auteur<<","<<version<<std::endl;
    	}
    	void main()
    	{
    		livre unlivre;
    		unlivre.modifiernom("");
    		unlivre.modifierauteur("");
    		unlivre.modifierversion(0);
    		unlivre.afficher();
    		getch();
     
    	}

  9. #9
    Alp
    Alp est déconnecté
    Expert éminent sénior

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Alors, plusieurs choses pour améliorer la qualité et sureté de ton code.

    1/ Utilise (si tu as le choix) std::string au lieu de char* pour tes chaînes de caractères. Tu trouveras std::string dans l'entête <string> (pas <string.h>, qui est un entête du langage C). Ca se manipule très facilement. Il y a une page dédiée aux strings dans la FAQ : http://cpp.developpez.com/faq/cpp/?page=strings

    2/ <conio.h> ne te servira à rien, et ce n'est pas un entête standard. Tu peux le lever.

    3/ Je ne suis pas sûr que le fait qu'il existe un constructeur ne prenant aucun argument soit correct. En effet, est-ce que ç'a un sens de construire un livre qui n'a ni nom, ni auteur, ni version ? Disons qu'il n'aurait probablement pas de contenu non plus, donc personne ne le lirait

    4/ Il va te falloir au moins une autre classe. Celle-ci pourra par exemple s'appeler bibliotheque, et elle maintiendra une collection de livres. Après, tu peux modéliser éventuellement les prêts de livres par une classe qui met en relation un client et un ou plusieurs livres, à toi de voir.

    Pour terminer, je te conseille de garder sous la main la FAQ C++ pendant que tu fais cela, elle est pleine de sagesse et de très bon conseil, et elle t'apprendra une quantité assez impressionnante de bonnes pratiques.

    Bon courage

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par hamady's Voir le message
    j'ai un petit problème avec ( error C2065: 'nouvversion'*: identificateur non déclaré)
    Bonjour,
    une simple relecture de ton code devrait te permettre de résoudre ce petit problème

    Sinon, peux-tu utiliser les std::string. Ce serait sans doute préférable dans un code C++ à la place des tableaux de char et des chaînes de type C.
    Si tu ne peux utiliser les string alors fais un petit tour côté FAQ sur les problèmes des pointeurs (problème de copie, RAII, exception safety, pointeur intelligents...).

    Dans la même veine, à la place du getch() hérité du C, tu peux t'intéresser à une approche C++ avec les flux.

    Enfin, ton main devrait retourner un entier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int main(){
    // ...
    return 0; // ou tout autre entier, avec en général :
    // 0 pour OK
    // 1 pour erreur
    // 2 pour info
    }

  11. #11
    Nouveau Candidat au Club
    Inscrit en
    Mai 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    salut, j'ai un soucis avec le visual c++ 2008, quand je débogue le programme on m'affiche les messages suivants
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    'projet.exe'*: Chargé 'C:\WINDOWS\system32\ntdll.dll'
    'projet.exe'*: Chargé 'C:\WINDOWS\system32\kernel32.dll'
    'projet.exe'*: Chargé 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.30729.1_x-ww_f863c71f\msvcr90d.dll'
    'projet.exe'*: Chargé 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.30729.1_x-ww_f863c71f\msvcp90d.dll'
    Le programme '[3152] projet.exe: Natif' s'est arrêté avec le code 0 (0x0).
    Merci d'avance de votre aide.

  12. #12
    Membre actif
    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    189
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 189
    Points : 213
    Points
    213
    Par défaut
    s'est arrêté avec le code 0 => le programme s'est bien exécuté.

  13. #13
    Nouveau Candidat au Club
    Inscrit en
    Mai 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    salut a tous voila je voudrais réaliser un menu principal pour ce projet, juste pour apprendre le c++, et je manque des conseils
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // Declaration du nom des classes que l'on va utiliser par la suite
    class Bibliotheque;
    class Ouvrage;
    class Exemplaire;
    // Liste les trois valeurs possible pour un accept
    enum OUVRAGE_STATUS
    {
        FALSE = false,
        TRUE = true,
        NOT_KNOWN,
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Filtre
    {
        public:
        virtual ~Filtre() {}
        virtual OUVRAGE_STATUS accept(Ouvrage* o) = 0;
        virtual bool accept(Exemplaire* e) = 0;
    };
    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
    // Definition de la classe exemplaire
    class Exemplaire
    {
        public:
            // Constructeur de la classe Exemplaire :
            // Trois parametres
            //  - dateAchat: la date d'achat de l'exemplaire par la bibliotheque
            //     (nombre de seconde depuis le 1er janvier 1970)
            //  - dateEdition: la date d'edition de l'exemplaire
            //     (nombre de seconde depuis le 1er janvier 1970)
            //  - ouvrage: un pointer (l'adresse) de l'objet ouvrage correspondant.
            Exemplaire(int dateAchat, int dateEdition, Ouvrage* ouvrage)
            // List d'initialisation des donnees membres
                : dateAchat_(dateAchat),
                  dateEdition_(dateEdition),
                  disponible_(dateAchat != 0 && dateEdition != 0),
                  ouvrage_(ouvrage)
            {
                // Corps du constructeur (vide)
            }
            // Fonction permettant de savoir si l'exemplaire
            // est disponible dans la bibliotheque ou non
            // La fonction est qualifie par le mot clef const car elle ne modifie
            // pas l'etat interne de l'objet
            bool estDisponible() const
            {
                return disponible_;
            }
            // Retourne la date d'achat
            int getDateAchat() const
            {
                return dateAchat_;
            }
            // Retourne la date d'achat
            int getDateEdition() const
            {
                return dateEdition_;
            }
            // Permet d'obtenir une reference vers l'objet ouvrage correspondant.
            Ouvrage& getOuvrage() const
            {
                return *ouvrage_;
            }
            // Il n'est pas necessaire d'ecrire des methode permettant de modifier
            // la date d'achat, la date d'edition ou encore l'ouvrage.
            // Ces informations ne sont pas amenee a changer dans le temps.
     
            // Cette methode permet d'emprunter un exemplaire
            void emprunter()
            {
                if (dateAchat_ != 0 && dateEdition_ != 0)
     
                    // Si l'exemplaire est emprunte,
                    // alors il n'est plus disponible
                    disponible_ = false;
            }
            // Cette methode permet de rendre un exemplaire a la bibliotheque
            void rendre()
            {
                if (dateAchat_ != 0 && dateEdition_ != 0)
                    // Si on rend l'exemplaire alors ce dernier est a nouveau
                    // disponible
                    disponible_ = true;
            }
     
        private:
            // Donnees membres (attributs).
            // L'etat de l'objet est prive. Il ne peut etre modifie que par
            // les methodes emprunter() et rendre().
            int dateAchat_;
            int dateEdition_;
            bool disponible_;
            Ouvrage* ouvrage_;
    }; // Fin de la definition de la classe exemplaire
    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
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    class Ouvrage
    {
        public:
            // Definition des valeurs possible pour format
            // static signifie ici que les donnees sont commune a l'ensemble des
            // instance de la classe. Il est conseille de toujours definir
            // la valeur des variable static hors de la definition de la classe.
            // En effet, il n'est pas possible d'initialiser tout type de donnees
            // directement dans la classe il est donc plus pratique de toujours
            // initialiser hors de la classe.
     
            // Si l'on veut utiliser la constante FORMAT_LIVRE on ecrira :
            // FORMAT_LIVRE si l'on est entrain de definir la classe ouvrage
            // Ouvrage::FORMAT_LIVRE si l'on est l'utilisateur de la classe
            // ouvrage.
            static const int FORMAT_LIVRE;
            static const int FORMAT_CD;
            static const int FORMAT_DVD;
            static const int FORMAT_PERIODIQUE;
            static const int FORMAT_CASSETTE;
     
            // Constructeur de la classe Ouvrage
            // Ici je n'utilise pas de liste d'initialisation
            // C'est une seconde facon d'ecrire les constructeur.
            // Il est neanmoins recommende d'utiliser la liste d'initialisation
            // partout ou c'est possible.
            // Lorsque que l'argument est un objet, il est recommande de toujours
            // utilise le passage de parametre par reference constante.
            // CF cours sur le cycle de vie et le constructeur par copie
            Ouvrage(const std::string& auteur, const std::string& titre,
                    const std::string& genre, int format)
            {
                auteur_ = auteur;
                titre_ = titre;
                genre_ = genre;
                format_ = format;
                exemplaires_.push_back(new Exemplaire(0, 0, this));
            }
            ~Ouvrage()
            {
                for(size_t i = 0 ; i < exemplaires_.size() ; ++i)
                    delete exemplaires_[i];
            }
            // Accesseurs
            // Afin d'eviter la copie de l'objet on retourne des references constante
     
            const std::string& getAuteur() const
            {
                return auteur_;
            }
            const std::string& getTitre() const
            {
                return titre_;
            }
     
            const std::string& getGenre() const
            {
                return genre_;
            }
            // Pour les types de bases (
            //  - char / short / int / long /
            //  - float / double /
            //  -  pointer / bool )
            // il n'est pas necessaire re retourner une reference constante.
            int getFormat() const
            {
                return format_;
     
            }
            // Retourne le nombre d'exemplaire de cet ouvrage
     
            int getNombreExemplaire() const
            {
                return exemplaires_.size();
            }
            // Retourne l'exemplaire de rang rang.
            Exemplaire* getExemplaire(int rang)
            {
                return exemplaires_.at(rang);
            }
            // Permet d'obtenir un exemplaire disponible parmis tous les exemplaires
            Exemplaire* getDisponible()
            {
                for (unsigned int i = 0 ; i < exemplaires_.size() ; ++i)
                {
                    // Ici on stocke des pointeurs vers des exemplaires. On doit
                    // donc utiliser l'operateur -> pour appeler la methode
                    // (fonction) estDisponible de la classe exemplaire.
                    if (exemplaires_[i]->estDisponible())
                        return exemplaires_[i];
                }
            }
            // Ajoute un nouvel exemplaire pour l'ouvrage courant.
            Exemplaire& creerExemplaire(int dateAchat, int dateEdition)
            {
                // Ici on utilise push_back pour ajouter a la fin du vecteur.
                // new permet de creer un objet alloue dynamiquement.
                // Tout objet alloue dynamiquement n'est pas detruit lorsque l'on
                // sort de la porte (bloc). L'objet va donc perdurer a la fin de
                // l'execution de la fonction.
                // Attention c'est a nous de gerer la memoire associe a cet objet.
                // Il est a la charge du programmeur de liberer cette memoire quand
                // l'objet n'est plus util.
                // CF cours sur la gestion des resources par le biais de
                // l'encapsulation.
                exemplaires_.push_back(new Exemplaire(dateAchat, dateEdition, this));
                return *exemplaires_.back();
            }
     
            void recherche(Filtre* f, std::vector<Exemplaire*>& resultat)
            {
                for(size_t i = 0 ; i < exemplaires_.size() ; ++i)
                {
                    if (f->accept(exemplaires_[i]))
                    {
                        resultat.push_back(exemplaires_[i]);
                    }
                }
            }
            // Il manque la fonction permettant de supprimer un exemplaire.
            // On traitera cela lors de la prochaine seance de TP.
        private:
            // Donnee membre privee.
            std::string auteur_;
            std::string titre_;
            std::string genre_;
            int format_;
            // Stocke l'ensemble des exemplaires d'un ouvrage
            std::vector<Exemplaire*> exemplaires_;
    }; // Fin de la definition de la class Ouvrage
    const int Ouvrage::FORMAT_LIVRE = 1;
    const int Ouvrage::FORMAT_CD = 2;
    const int Ouvrage::FORMAT_DVD = 3;
    const int Ouvrage::FORMAT_PERIODIQUE = 4;
    const int Ouvrage::FORMAT_CASSETTE = 5;
     
    // Definition de la classe bibliotheque.
    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
    class Bibliotheque
    {
        public:
            // Constructeur
            Bibliotheque(const std::string& nom, const std::string& adresse)
                : nom_(nom), adresse_(adresse)
            {
                // Le constructeur n'a plus rien a faire
                //nom_ = nom;
                //adresse_ = adresse;
            }
            ~Bibliotheque()
            {
                for(size_t i = 0 ; i < ouvrages_.size() ; ++i)
                    delete ouvrages_[i];
            }
            // Accesseur
            const std::string& getNom() const
            {
                return nom_;
            }
            const std::string& getAdresse() const
            {
                return adresse_;
            }
            // Retourne le nombre d'ouvrages references dans la bibliotheque
            int getNombreOuvrage() const
            {
                return ouvrages_.size();
            }
            // Retourne le nombre d'exemplaires tout ouvrage confondus que possede
            // la bibliotheque
            int getNombreExemplaire() const
            {
                int total = 0;
                // A COMPLETER par vous.
                for(size_t i = 0 ; i < ouvrages_.size() ; ++i)
                {
                    total += ouvrages_[i]->getNombreExemplaire();
                }
                return total;
            }
            // Ajouter un nouvel ouvrage a la bibliotheque
            Ouvrage& ajouterOuvrage(const std::string& auteur,
                                    const std::string& titre,
                                    const std::string& genre,
                                    int format)
            {
                // (allocation memoire dynamique)
                ouvrages_.push_back(new Ouvrage(auteur, titre, genre, format));
                return *ouvrages_.back();
            }
            // Ce qu'il manque :
            // - Fonction permettant de parcourir la liste des ouvrages
            //   C'est identique au parcours des exemplaires associe a un ouvrage
     
     
            // Fonction de recherche: resultat un ensemble d'exemplaire
     
            std::vector<Exemplaire*> recherche(Filtre* f)
            {
                std::vector<Exemplaire*> resultat;
                for(size_t i = 0 ; i < ouvrages_.size() ; ++i)
                {
                    if (f->accept(ouvrages_[i]))
                    {
                        ouvrages_[i]->recherche(f, resultat);
                    }
                }
                return resultat;
            }
     
        private:
            // Nom de la bibliotheque
            std::string nom_;
            // Adresse
            std::string adresse_;
            // Stocke l'ensemble des ouvrages d'une bibliotheque.
            std::vector<Ouvrage*> ouvrages_;
    }; // Fin de la definition de la classe bibliotheque
     
     
    // La classe Filtre Auteur permet de selectionner les auteurs tel que decrit
    // par la chaine de caractere auteur.
    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
    class FiltreAuteur : public Filtre
    {
        public:
        // constructeur
        FiltreAuteur(const std::string& auteur)
            : auteur_(auteur)
            {
            }
        // Si le nom de l'auteur de l'ouvrage correspond a la chaine de caractere
        // auteur_ alors authoriser la recherche dans les exemplaires
        OUVRAGE_STATUS accept(Ouvrage* o)
        {
            if (o->getAuteur() == auteur_)
                return TRUE;
            return FALSE;
        }
        // Si l'ouvrage correspond alors tous les exemplaires egalement.
        bool accept(Exemplaire* e)
        {
            return true;
        }
        private:
            std::string auteur_;
    };
     
    class FiltreDisponible : public Filtre
    {
        public:
            OUVRAGE_STATUS accept(Ouvrage* o)
            {
                return NOT_KNOWN;
            }
            bool accept(Exemplaire* e)
            {
                if (e->estDisponible())
                    return true;
                return false;
            }
    };
    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
    class FiltreOu : public Filtre
    {
        private:
            Filtre* f1;
            Filtre* f2;
        public:
            FiltreOu(Filtre* f1, Filtre* f2)
            {
                this->f1 = f1;
                this->f2 = f2;
            }
            // Mauvais perte de genericite
            //FiltreOu(std::string& au1, std::string& au2)
            //{
            //    f1 = new FiltreAuteur(au1);
            //    f2 = new FiltreAuteur(au2);
            //}
     
            OUVRAGE_STATUS accept(Ouvrage* o)
            {
                OUVRAGE_STATUS tmp = f1->accept(o);
                if (tmp == TRUE)
                    return TRUE;
                OUVRAGE_STATUS tmp2 = f2->accept(o);
                if (tmp2 == TRUE)
                    return TRUE;
     
                if (tmp2 == NOT_KNOWN || tmp == NOT_KNOWN)
                    return NOT_KNOWN;
                return FALSE;
            }
            bool accept(Exemplaire* e)
            {
                if (f1->accept(e))
                    return true;
                return f2->accept(e);
            }
    };
    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
    class FiltreNon : public Filtre
    {
        public:
            FiltreNon(Filtre* f)
                : f_(f) {}
     
            OUVRAGE_STATUS accept(Ouvrage* o)
            {
                tmp = f_->accept(o);
                if (tmp == TRUE)
                    return FALSE;
                else if (tmp == FALSE)
                    return TRUE;
                return tmp;
            }
            bool accept(Exemplaire* o)
            {
                if (tmp == NOT_KNOWN)
                    return !f_->accept(o);
                return TRUE;
            }
     
        private:
            Filtre* f_;
            OUVRAGE_STATUS tmp;
    };
    et voila j'ai eu un programme principal pour le filtre
    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
    // Programme de test / point d'entree de l'application
    int main()
    {
    	Bibliotheque b("UVSQ", "Batiment Buffon, 45 avenue des etats unis, 78035 Versailles CEDEX");
    	Ouvrage &o = b.ajouterOuvrage("Claude Delannoy", "Programmer en langage C++",
    	                    "Culture numerique", Ouvrage::FORMAT_LIVRE);
        o.creerExemplaire(1, 5);
        o.creerExemplaire(2, 6).emprunter();
        Ouvrage &o1 = b.ajouterOuvrage( "Herb Sutter", "Exceptional C++",
                                        "Culture numerique", Ouvrage::FORMAT_LIVRE);
        o1.creerExemplaire(3, 7);
        o1.creerExemplaire(4, 8);
        // Ajouter des ouvrages et des exemplaires ici.
        Ouvrage &o2 = b.ajouterOuvrage( "Inconnu", "Le C++ pour les null",
                                        "Inutile", Ouvrage::FORMAT_LIVRE);
     
     
     
    	std::cout << "Nombre exemplaires : "
    	    << b.getNombreExemplaire() << std::endl;
     
     
        FiltreDisponible filtre0;
        std::vector<Exemplaire*> resDisponible = b.recherche(&filtre0);
        std::cout << "Resultats du filtre disponible(" << resDisponible.size()
            << "): " << std::endl;
        for (size_t i = 0; i < resDisponible.size() ; ++i)
        {
            std::cout << i << ": " << resDisponible[i]->getOuvrage().getAuteur()
                      << ", " << resDisponible[i]->getOuvrage().getTitre()
                      << ", " << resDisponible[i]->getDateAchat()<< std::endl;
        }
        // Test filtre Non sur exemplaire
        FiltreNon nonDispo(&filtre0);
        std::vector<Exemplaire*> resNonDispo = b.recherche(&nonDispo);
        std::cout << "Resultats du filtre non disponible(" << resNonDispo.size()
                    << "): " << std::endl;
        for (size_t i = 0 ; i < resNonDispo.size() ; ++i)
        {
            std::cout << i << ": " << resNonDispo[i]->getOuvrage().getAuteur()
                << ", " << resNonDispo[i]->getOuvrage().getTitre()
                << ", " << resNonDispo[i]->getDateAchat() << std::endl;
        }
     
        // Test filtre auteur
        FiltreAuteur filtre1("Claude Delannoy");
        std::vector<Exemplaire*> resClaudeDelannoy = b.recherche(&filtre1);
        std::cout << "Resultats du filtre Claude Delannoy("
                  << resClaudeDelannoy.size()
                  << "): " << std::endl;
        for (size_t i = 0 ; i < resClaudeDelannoy.size() ; ++i)
        {
            std::cout << i << ": " << resClaudeDelannoy[i]->getOuvrage().getAuteur()
                      << ", " << resClaudeDelannoy[i]->getOuvrage().getTitre()
                      << ", " << resClaudeDelannoy[i]->getDateAchat() << std::endl;
        }
        // Test filtre non sur ouvrage
        FiltreNon nonClaude(&filtre1);
        std::vector<Exemplaire*> resNonClaude = b.recherche(&nonClaude);
        std::cout << "Resultats du filtre Non Claude Delannoy("
                  << resNonClaude.size()
                  << "): " << std::endl;
        for (size_t i = 0 ; i < resNonClaude.size() ; ++i)
        {
            std::cout << i << ": " << resNonClaude[i]->getOuvrage().getAuteur()
                      << ", " << resNonClaude[i]->getOuvrage().getTitre()
                      << ", " << resNonClaude[i]->getDateAchat() << std::endl;
        }
     
        // Test du Filtre ou sur ouvrage
        FiltreAuteur filtre2("Herb Sutter");
        FiltreOu ou(&filtre1, &filtre2);
        std::vector<Exemplaire* > resOu = b.recherche(&ou);
        std::cout << "Nombre de resultat de la recherche: " <<
            resOu.size() << std::endl;
        std::cout << "Resultats: " << std::endl;
        for(size_t i = 0 ; i < resOu.size() ; ++i)
        {
            std::cout << resOu[i]->getOuvrage().getAuteur() << std::endl;
        }
        std::cout << "Filtre: Disponible ou Non Disponible" << std::endl;
        FiltreOu tous(&filtre0, &nonDispo);
        std::vector<Exemplaire*> resOu2 = b.recherche(&tous);
        std::cout << "Resultats: " << resOu2.size() << std::endl;
        std::cout << "Nombre Exemplaires total: " << b.getNombreExemplaire() << std::endl;
     
    	//return 0;
    	getch();
    }

  14. #14
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut, et bienvenue sur le forum.

    Je dois avouer qu'il y a déjà de l'idée et que tu partage plus ou moins bien les responsabilités (pour ce que j'ai lu de manière transversale du code )

    Cependant,je voudrais attirer ton attention sur quelques points, qui, bien qu'ils ne répondent pas forcément à ta question sont de nature à t'apporter une aide précieuse :
    au sujet des booléens
    les booléens (true et false) sont définis ainis:
    • false est représenté par une valeur fausse (typiquement 0)
    • true est représenté toutes valeurs ne pouvant pas être considérée comme fausse
    c'est à dire que, si, typiquement true est typiquement représenté par 1, il s'applique également à toute valeur différente de 0

    De plus, si je comprend que le statut puisse être valide ou non (vrai ou faux), j'avoue ne pas très bien comprendre l'utilité d'un statut "inconnu"...

    Tout cela me fait m'interroger grandement sur l'utilité de l'énumération OUVRAGE_STATUS en générale et de sa dernière valeur en particulier
    Les listes d'initialisation
    Lorsque tu définis un constructeur, il est possible et conseillé d'utiliser les listes d'initialisations pour initialiser les différents membres de la classe.

    En effet, si le compilateur ne supporte pas un concept que l'on appelle le NRVO, le fait de ne pas les utiliser va provoquer un comportement d'initialisation aux valeurs par défaut suivi d'une assignation de valeur, qui peut elle-même être le résultat d'une copie et d'un "swap" des membres, alors que le fait d'utiliser les liste d'initialisation permet d'appeler le constructeur adéquat (le constructeur par copie, ou le constructeur normal) et de rendre ce seul appel suffisant.

    Si, pour des données de types primitives, cela ne représente pas vraiment d'avantages (mais ne représente en tout cas aucun inconvénient), pour des données personnalisées complexes (principalement toutes les données manipulant des collections d'autres objet), cela peut représenter un gain de temps et d'utilisation de la mémoire assez important

    Pour utiliser la liste d'initialisation, il "suffit" de placer la parenthèse fermante de la liste d'arguments et l'accolade ouvrante du bloc d'instructions du constructeur le symbole deux points " : " suivi par l'appel explicite des constructeurs particuliers de chaque membre (de préférence dans l'ordre de leur déclaration), séparé par une virugule

    Cela donne un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MaClass::MaClass(Type1 m1, Type2 m2, Type3 m3/*,...*/):
             membre_1(m1), membre_2(m2), membre_3(m3)/*,... */
    {
        /* il n'y a plus qu'à faire les tests de cohérences éventuels */
    }
    Au sujet de l'utilisation des pointeurs et de l'allocation dynamiqueDe manière générale, le langage nous donnes un maximum de possibilités de nous passer de l'utilisation de pointeurs en dehors des cas où l'on n'a pas d'autres choix...

    Les collections d'objets, dont la classes vector que tu utilise, sont l'un de ces moyens.

    Au final, la gestion dynamique de la mémoire ne se justifie plus que dans quelques cas bien particuliers:
    • Lorsque l'objet créé a une durée de vie différente de l'objet qui le crée (et principalement si l'objet créé doit "survivre" à l'objet qui l'a créé)
    • Lorsque l'on souhaite utiliser le polymorphisme (créer un objet d'un type dérivé en le faisant passer pour un objet du type de base)
    et l'utilisation même des pointeurs se limite, outre les deux cas sus-cités, au cas où l'on veut disposer d'une référence à l'objet contenant dans l'objet contenu.

    Ainsi, si l'utilisation d'un pointeur sur Ouvrage se justifie dans un exemplaire, on peut malgré tout estimer qu'un exemplaire n'a aucune raison à "survivre" à un ouvrage donné (comment pourrait on avoir un exemplaire d'un ouvrage ... inexistant )...

    De plus, les conteneurs de la STL ne sont pas particulièrement adaptés lorsqu'il s'agit de contenir des pointeurs sur des objets dont la mémoire a été allouée dynamiquement, ne serait-ce que parce qu'il faut penser à libérer soi-même la mémoire allouée dynamiquement avant d'effacer l'élément (ou les éléments) du conteneur.

    L'idéal dans ce cas est soit d'utiliser des pointeurs dits "intelligents" (tels que shared_ptr), soit d'utiliser l'un des conteneurs particuliers fournis par boost (et qui va faire me semble-t-il son apparition dans la nouvelle norme) et dédié à la gestion de pointeurs: Boost:ointer Container
    Au sujet des commentaires
    Soyons francs: le débats sur l'utilité des commentaires est loin d'être fini...

    Mais s'il y a consensus sur quelque chose, c'est que, si commentaires il y a, ils doivent être cohérents et apporter certaines précisions que l'on ne trouve pas dans le code...

    Je me doute qu'il s'agit d'un copier / coller malheureux, mais, d'un point de vue de la cohérence, on peut estimer que cet extrait code peut faire mieux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            // Retourne la date d'achat
            int getDateEdition() const
            {
                return dateEdition_;
            }
    De plus, on peut se demander, même si le commentaire était cohérent (Retourne la date d'édition), si un tel commentaire apporte vraiment une précision que l'on ne trouve pas dans le code...

    Quelque part, le nom même de la fonction permet de savoir sans équivoque possible ce qu'elle est sensée faire
    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

  15. #15
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour,
    C'est un code assez bien construit
    Quelques commentaire en vrac :

    1. Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      enum OUVRAGE_STATUS
      {
          FALSE = false,
          TRUE = true,
          NOT_KNOWN,
      };
      Personnellement je n'aime pas les constantes maisons qui ressemble à TRUE/FALSE quelque soit la casse. Je préfère des valeurs plus explicites qui présentent moins de risque de conflit :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      enum OUVRAGE_STATUS
      {
          NOT_AVAILABLE = false,
          AVAILABLE = true,
          NOT_KNOWN,
      };

    2. Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      class Filtre
      {
          public:
          virtual ~Filtre() {}
          virtual OUVRAGE_STATUS accept(Ouvrage* o) = 0;
          virtual bool accept(Exemplaire* e) = 0;
      };
      On préfère utiliser le pattern NVI (non virtual interface) pour la définition des interfaces :
      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
      class Filtre
      {
          public:
          virtual ~Filtre() {}
          OUVRAGE_STATUS accept(Ouvrage* o)
          {
               do_accept(o);
          }
          bool accept(Exemplaire* e)
          {
               do_accept(e);
          }
          private :
          virtual OUVRAGE_STATUS do_accept(Ouvrage* o) = 0;
          virtual bool do_accept(Exemplaire* e) = 0;
      };
      // Puis :
      class FiltreAuteur : public Filtre
      {
          public:
          // constructeur
      // etc..
          private :
          // Si le nom de l'auteur de l'ouvrage correspond a la chaine de caractere
          // auteur_ alors authoriser la recherche dans les exemplaires
          OUVRAGE_STATUS do_accept(Ouvrage* o)
      // etc.
      Cette approche sépare les responsabilités : la méthode non virtuelle pour les utilisateurs de la classe, la méthode virtuelle pour les classes dérivées. C'est en général un gage de meilleure souplesse face aux évolutions et s'intègrent mieux avec une approche par contrat.
    3. Ouvrage a un membre vecteur de pointeurs de Exemplaire (idem Bibliotheque a un membre vecteur de pointeurs d'ouvrage). Je ne vois pas l'intérêt d'avoir un vecteur de pointeur. Un vecteur de valeur devrait suffire car tu n'en fais pas d'utilisation polymorphique (pas de classe dérivées d'Expemplaire ou Ouvrage) et ce ne sont pas des objets partagés.
      Si tu souhaites maintenir un vecteur de pointeur, alors il te faut soit interdire la copie de ta classe soit penser à gérer correctement cette copie (fais une recherche sur pointeur intelligent dans le forum). En outre, il faudrait gérer la possibilité d'une levée d'exception.
    4. Tu gagnerais à consulter les algos de la STL qui pourraient t'aider à réécrire quelques unes de tes fonctions. Par exemples :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      Exemplaire* getDisponible()
      {
        std::vector<Exemplaire*>::const_iterator it = std::find_if(
           exemplaires_.begin(),
           exemplaires_.end(),
           std::mem_fun(&Exemplaire::estDisponible)
        );
        if(it!=exemplaires_.end()){
           return *it;
        }
        return NULL;
      }

Discussions similaires

  1. Gestion d'une bibliothèque
    Par mimosa803 dans le forum Diagrammes de Classes
    Réponses: 5
    Dernier message: 30/05/2013, 09h35
  2. BiblioISSATS : Gestion d'une bibliothèque universitaire
    Par Chatbour dans le forum Vos contributions VB6
    Réponses: 3
    Dernier message: 25/10/2010, 17h40
  3. [MCD] Gestion d'une bibliothèque
    Par LhIaScZkTer dans le forum Schéma
    Réponses: 15
    Dernier message: 12/06/2009, 09h18
  4. SQlite : Gestion d'une bibliothèque
    Par comtois dans le forum PureBasic
    Réponses: 0
    Dernier message: 30/11/2008, 20h35
  5. Gestion d'une bibliothèque en Windev
    Par Lenalyon dans le forum WinDev
    Réponses: 5
    Dernier message: 23/08/2007, 15h01

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