j'ai quelques petits problemes avec les pointeurs et les tableaux dynamique .
pb n01 :dans la fonction stcker j'ai deux parametres , l'entier n est le nombre des exemplaires que je fois ajouter , mais je n'ai pas trouver comment l'utiliser dans la fonction push.back !
pb n02 : l'appel de la fonction Afficher qui est dans la classe "exemplaire" et qui a l'accés aux autres attribut avec des accesseurs ; la fonction afficher est mentionné en commentaire dans la fin de mon code !
merci !
class Bibliotheque{
private:
vector<Exemplaire*> exemplaire;
string name ;
public:
Bibliotheque(string testnom):name(testnom)
{
cout<< "La bibliothèque" <<name<< "est ouverte !"<<endl;
}
string getname(){
return name;
}
void stocker( Exemplaire* autre,int n )
{ exemplaire.push_back(autre); }
void lister_exemplaires ()
{
/*for (unsigned int i(0); i < exemplaire.size(); i++) {
cout << exemplaire[i]->Afficher()<< endl;
}*/
for(auto const& ex : exemplaire) {
ex->Afficher();
}
}
1
class Exemplaire {
1
private : Oeuvre oeuvre
public :
void Afficher()
{
cout<< "Exemplaire de :" << oeuvre.setTitre()<<" , en " <<oeuvre.setLangue()<<endl ;
}
Essaie d'indenter correctement ton code, c'est vraiment crade pour le moment :/
1/ J'ai pas compris ton problème avec le paramètre n? ajouter n fois autre dans ton vector d'exemplaires? Si oui, il suffit de faire une boucle for qui va jusqu'a n. 2/J'ai pas compris ton 2eme problème, désolé, si ce n'est que t'utilises le setter a la place du getter dans ta fonction Exemplaire::afficher(). C 'est quoi ton message d'erreur?
- Edité par KirbXCoucou 1 août 2019 à 8:20:21
« Je n’ai pas besoin de preuve. Les lois de la nature, contrairement aux lois de la grammaire, ne permettent aucune exception. » D. Mendeleïev
Vraisemblablement tu as fais quelque part un "using namespace std" qui est fortement déconseillé. Une recherche sur le forum pourra te donner les raisons et te le confirmer.
Il y a une raison particulière à utiliser le tas (utilisation de pointeur nu) dans ton exemple ? Les pointeurs nus sont généralement déconseillé (et là aussi une recherche permettra de te le confirmer). Bien que déconséillé, je m'atendrai à voir* quelque part un
autre = new Exemplaire[n]; //(et le delete qui va avec)
EDIT: /!\ Je m'attends à voir** d'autres choses pour faire les choses correctement (surcharge de constructeur de copie, surcharge d'opérateur d'attribution (=) etc). -> Principe d'on j'oublies le nom à chaque fois qui te dis : "Si tu peux te tromper UN JOUR TU TE TROMPERAS" C'est pourquoi les pointeurs nus sont déconseillé car il y a une possibilité de memory leaks et donc les smarts pointers sont à privilégiées (sauf exceptions).
(*)(**) Si tu as bien compris, je ne m'attends pas à voir cela (cf les raisons ci-dessus).
Dans l'idéal, il nous faudrait les erreurs fournies pour une aide optimale.
Pour les getter/setter, je suis pas fan. En c++ il faut raisonner en "fonctionnalités" et non pas en "gestion d'attributs". Je pense (en toute modestie, je laisserai expert confirmer ou non, mon propos) que tu as un soucis de conception.
Déjà, tu semble vouloir créer un tableau de pointeur. C'est une très mauvaise idée pour toute une série de raisons (*)! Crée plutôt un tableau d'Examplaire(s), transmet ton Examplaire par référence constante à ta fonction stocker, de manière à pouvoir en faire une copie lors du push_back
(*) je te les expliquerai si tu y tiens vraiment
Enfin, pourquoi n'indiquerais tu pas, tout simplement, le nombre d'exemplaire dont dispose la bibliothèque de l'oeuvre directement dans ta classe Exemplaire et, tant qu'à faire, le nombre d'exemplaire "prêtés", sous une forme qui pourrait être proche de
class Exemplaire{
public:
Exemplaire(Oeuvre const & oeuvre, size_t quantite):oeuvre{oeuvre}, quantite{quantite}{
}
void prete(){
assert(prets < quantite && "impossible de preter plus d'exemplaires que ceux dont on dispose");
++prets;
afficher("prete");
}
void rendu(){
assert(prets>0 && "impossible de rendre un exemplaire inexistant");
-- prets;
afficher("rendu")
}
/* on peut recevoir de nouveaux exemplaires : cela augmente la quantité total */
void recevoir(size_t nouveaux){
quantite += nouveaux);
}
/* certains exemplaires sont trop abimés, on doit se résoudre à les jeter
* (ou on les considère comme "perdus" quand il n'ont pas été rendu après XXX temps
* on jette les exemplaires un à un
*/
void jeter(){
assert(quantite > 1 && "impossible de jeter un exemplaire inexistant");
--quantie;
}
private:
void afficher(std::string const & inout){
std::cout<<"exemplaire de "<<oeuvre.titre()
<<" de "<<oeuvre.auteur()
<<" "<<inout<"\n"
<<"on a actuellement "<<quantite-prets
<<" exemplaires disponibles pour "
<<prets <<"exemplaires pretes\n";
}
Oeuvre const & oeuvre;
size_t quantite;
size_t prets
};
(je me suis basé sur le principe que la classe Oeuvre permet d'accéder au titre et à l'auteur de l'ouvrage
L'ajout d'un nouvel ouvrage pourrait se faire sous la forme de
int main(){
Bibliotheque bib;
/* on peut ajouter un nouvel ouvrage (un nouveau titre,
* avec l'auteur correspondant) à la bibliothèque
*/
auto const & ouvrage = bib.ajouterOuvrage("Les miserables","Victor Hugo");
/* après avoir créé l'ouvrage, on peut rajouter
* le nombre d'exemplaires qu'on vient de recevoir
*/
bib.ajouterExemplaire(Exemplaire{ouvrage, 3});
try{
auto const & ouvrage = bib.chercherOuvrage("titre","auteur");
/* si l'ouvrage existe, on peut chercher les exemplaires
*/
auto & exemplaire = bib.exemplaires(ouvrage);
/* on peut préter un exemplaire, récupéréer
* un exemplaire prété, recevoir de nouveaux
* exemplaires ou ... jeter un exemplaire trop
* abimé ici
*/
}catch(ExemplaireNotFound & e){
std::cout<<e.what();
}
}
Ceci étant dit, ta bibliothèque devrait, au final, prendre une forme très proche de la notion de base de données relationnelles, et, a priori, chaque exemplaire d'un ouvrage devrait avoir un numéro d'ordre qui lui est propre, pour, justement, être en mesure de déterminer qui a loué quel exemplaire (de quel ouvrage) à quel moment (et pouvoir, le cas échéant, envoyer un rappel si l'ouvrage ne revient pas en temps et en heures, voire, imposer une amende pour le retard)
Chaque oeuvre devrait donc permettre d'accéder, en plus du titre et de l'auteur, à un identifiant qui lui est propre, qui pourrait servir de "relation" entre l'oeuvre et les (éventuels multiples) exemplaires de l'oeuvre en question, et chaque exemplaire d'une oeuvre devrait avoir un identifiant qui lui est propre pour pouvoir le distinguer des autres exemplaires de la même oeuvre.
En outre, chaque client de la bibliothèque devrait lui aussi pouvoir être identifié de manière unique (pour qu'on n'aille pas engueuler Gaston parce qu'il est soit disant en retard pour rendre un livre, alors que c'est Henry qui l'a emprunté :P)
Ces deux identifiants peuvent parfaitement être de simples valeur numériques (auto incrémentées), avec une valeur (std::numeric_limits<size_t>::max() ) permettant de représenter un identifiant inexistant (pour éviter le recours au try ... catch qui n'a normalement rien à faire là).
Tout cela me fait penser que nous aurions sans doute largement intérêt à aborder le problème sous la forme d'un ECS, avec les composants:
Et, bien sur, des "tables adaptée à chacun de ces composants (une std::map<id, composant> me semblant largement suffisante dans le cas présent pour la plupart de ceux-ci )
L'ajout d'un nouvel exemplaire d'une oeuvre quelconque devrait alors permettre à l'utilisateur de la bibliothèque de récupérer l'identifiant associé à cet exemplaire particulier, de manière à pouvoir coller une étiquette qui permettant de l'identifier lors du prêt/ de la remise (voir, lorsqu'il est jeté parce qu'il est trop abimer)
Je vais te laisser te renseigner sur la notion d'ECS (Entity Component System), mais je reste disposé à t'indiquer comment t'y prendre en cas de besoin
- Edité par koala01 1 août 2019 à 20:09:28
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Bonjour , donc j'ai quelques questions ! parceque je n'ai pas bien compris les tableaux dynamique , dans mon probléme :
vous avez utilisé la fonction ajouterOuvrage et apré l'ajout d'un ouvrage la fonction ajouterExemplaire , ça cest dans le main mais comment les définir dans la classe bibliothèque ! avec deux parametre : ouvrage et n le nombre .
un aute problème que j'ai rencontré : c'est avec le nom de l'auteur , dans la classe oeuvre j'ai pu utilisé la methode getNom qi retourne le nom de l'auteur car auteur est un des attributs de cette classe , mais dans la classe exemplaire je ne peux plus utiliser la methode getNom .
et une fonction ajouterExemplaire qui prendraiet la forme
Exemplaire & Bibliotheque::ajouterExemplaire(Exemplaire const & ex){
tabExemplaires.push_back(ex);
/* en cnsidérant que tabExemplaires est un std::vector<Exemplaire> */
return tabExemplaires[tabExemplaires.size()-1];
}
(avec la classe Exemplaire telle que je te l'ai montrée plus tôt )
MohamedSoheib a écrit:
koala01 ,
Bonjour , donc j'ai quelques questions ! parceque je n'ai pas bien compris les tableaux dynamique , dans mon probléme :
vous avez utilisé la fonction ajouterOuvrage et apré l'ajout d'un ouvrage la fonction ajouterExemplaire , ça cest dans le main mais comment les définir dans la classe bibliothèque ! avec deux parametre : ouvrage et n le nombre .
un aute problème que j'ai rencontré : c'est avec le nom de l'auteur , dans la classe oeuvre j'ai pu utilisé la methode getNom qi retourne le nom de l'auteur car auteur est un des attributs de cette classe , mais dans la classe exemplaire je ne peux plus utiliser la methode getNom .
Justement, en ajoutant une donnée membre (sous la forme d'une référence constante représentant l'oeuvre), tu pourrais modifier la classe Exemplaire pour lui donner une forme proche de
lass Exemplaire{
public:
Exemplaire(Oeuvre const & oeuvre, size_t quantite):oeuvre{oeuvre}, quantite{quantite}{
}
void prete(){
assert(prets < quantite && "impossible de preter plus d'exemplaires que ceux dont on dispose");
++prets;
afficher("prete");
}
void rendu(){
assert(prets>0 && "impossible de rendre un exemplaire inexistant");
-- prets;
afficher("rendu")
}
/* on peut recevoir de nouveaux exemplaires : cela augmente la quantité total */
void recevoir(size_t nouveaux){
quantite += nouveaux);
}
void jeter(){
assert(quantite > 1 && "impossible de jeter un exemplaire inexistant");
--quantie;
}
std::string const & titre() const{
return oeuvre.titre();
}
const std::string const & auteur() ocnst{
return oeuvre.auteur;
}
private:
void afficher(std::string const & inout){
std::cout<<"exemplaire de "<<oeuvre.titre()
<<" de "<<oeuvre.auteur()
<<" "<<inout<"\n"
<<"on a actuellement "<<quantite-prets
<<" exemplaires disponibles pour "
<<prets <<"exemplaires pretes\n";
}
Oeuvre const & oeuvre;
size_t quantite;
size_t prets
};
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
je pense que vous m'avez pas bien compris dans quelques points !
voici mon code complet ; j'ai trouvé 2 probleme principaux des deux fonctions des vector , et deux problemes d'appel aux attributs privés sont ts mentionné dans des commentaires
#include <iostream>
#include <vector>
#include <string>
using namespace std;
/*******************************************
* Completez le programme a partir d'ici.
*******************************************/
class Auteur
{
private:
string nom ;
bool indication ;
public:
Auteur(string testNom, bool testIndic):nom(testNom),indication(testIndic)
{}
Auteur(string test)
{ nom=test;
indication=false ;
}
void getNom(string name )
{
nom=name ;
}/*
void getPrix(bool ind )
{
indication=ind ;
}*/
string setNom()
{
return nom ;
}
bool setPrix()
{
return indication;
}
~Auteur(){};
};
class Oeuvre {
private:
string titre ,langue ;
Auteur auteur ;
public:
Oeuvre (string testtitre , Auteur const& autre ,string testLangue ):titre(testtitre),auteur(autre),langue(testLangue)
{}
/*
void getTitre(string testitre)
{
titre=testitre ;
}
void getauteur(Auteur const& testauteur)
{
auteur.nom=testauteur.nom ;
}*/
string setLangue()
{
return langue ;
}
string setTitre()
{
return titre ;
}
Auteur setauteur()
{
auteur.setNom() ;
}
void afficher(){
cout << titre<< ","<< auteur.setNom()<< ", en " <<langue <<endl;
}
~Oeuvre(){
cout << "L'\oeuvre " << titre << "," << auteur.setNom() << " , en " << langue << " n'\est plus disponible. "<<endl;
}
};
class Exemplaire {
private:
Oeuvre oeuvre ;
public:
Exemplaire( Oeuvre const& autre):oeuvre(autre)
{
cout<<"Nouvel exemplaire de :"<<oeuvre.setTitre()<< ", en " << oeuvre.setLangue() <<endl;
}
Exemplaire(Exemplaire const& autre ):oeuvre(autre.oeuvre)
{
cout << "Copie d’un exemplaire de :" <<oeuvre.setTitre()<<", en " << oeuvre.setLangue() <<endl;
}
~Exemplaire()
{
cout << "Un exemplaire de " <<oeuvre.setTitre() << /*"," << oeuvre.setauteur() <<*/" , en " << oeuvre.setLangue()<< " a été jeté !" <<endl;
}
Oeuvre getOeuvre()
{
return oeuvre;
}
void Afficher()
{
cout<< "Exemplaire de :" <<endl;/*<< oeuvre.setTitre()<</*"," <<oeuvre.setauteur()<<" , en " <<oeuvre.setLangue()<<endl ;
*/}
problemes avec les pointeurs et tableau dnamique )
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
« Je n’ai pas besoin de preuve. Les lois de la nature, contrairement aux lois de la grammaire, ne permettent aucune exception. »
D. Mendeleïev