@Equinoxe : c'est pas précisé. Tu fais comme tu veux. Mais quelqu'un soucieux de l'optimisation ne chargerait pas tout... surtout si tu imagines une bibliothèque avec autant de livres que wikipedia a d'articles...
Après, une petite astuce consisterait à découper en plusieurs fichiers selon le genre (de 0 à 9 pour commencer)...
Sauf que même 1M d'articles avec des tailles de (10 (numero) + 20 (Titre) + 20 (Genre) + 20 (Auteur) = 70) octets fait à peine 70 Mo.
Sur ce point, je pense que même tout wikipédia (qui ne doit pas contenir plus de 10 millions d'articles, soit 700Mo) devrait tenir en mémoire, même en considérant un léger poids supplémentaire de moins d'un Mo pour les variables temporaires, de ~10Mo pour toutes les informations nécessaires pour enregistrer les 10M articles, et encore 700 Mo en cas de nécessité de variable temporaire copiant tout la BDD (mauvaise prog' + requête particulière, pour mon cas tous les résultats d'une recherche sont copiés), soit un total d'environ 1410Mo, ce qui tient largement.
Par contre, un B-Tree-like devient nettement plus complexe si on veut gérer l'accès à la mémoire "disque", et devient nettement plus lent dès qu'on va rechercher par titre, par exemple.
Enfin, j'ai terminé le niveau 2 pour le moment, je m'attaquerai au 3 demain.
ouai mais bon 70MO dans la mémoire c'est du gaspillage... pour un texte sur console, la lecture sur le disque est tellement plus simple (je sais pas si c'est possible d'avoir des événements par contre sur console )
ouai mais bon 70MO dans la mémoire c'est du gaspillage... pour un texte sur console, la lecture sur le disque est tellement plus simple (je sais pas si c'est possible d'avoir des événements par contre sur console )
Hum, tu peux récupérer les évents du clavier uniquement à la base (avec la bibli standard j'entends)...
Quand on parle d'une appli biblio, faite pour tourner sur un serveur et être accédée par des clients (à la base), le serveur devrait avoir au moins 1Go de RAM, avec ... 128 Mo (J'avance un chiffre au pif, il me semble qu'une distrib' linux console prend encore moins) de RAM pour l'OS, il reste 896Mo de RAM réservée au programme. Et il est de plus en plus dur de n'avoir qu'un Go de RAM, donc je pense que 70Mo ne sont pas trop (et c'est déjà à condition d'avoir 1M de livres dans la bibliothèque, ce qui, il me semble, est relativement rare. ).
@Equinoxe: L'affichage des messages par les différentes classes est là pour faire pratiquer. Le but est de placer les messages au bon endroit (constructeur, destructeur, etc.) afin d'obtenir l'affichage voulu. Cela fait réviser l'ordre d'appel des constructeurs/destructeurs etc.
#ifndef SHELF_H_INCLUDED
#define SHELF_H_INCLUDED
#include <vector>
#include "main.h"
#include "Book.h"
class Shelf
{
public :
Shelf();
~Shelf();
id addBook(Book*);
id addBook(Author,std::string,std::string);
id currentId(void);
int removeBook(Book*);
int removeBook(id);
void show(void);
int showOne(id);
int showByAuthor(Author);
int showByType(std::string);
Book* book(id);
private :
std::vector<Book*> m_books;
unsigned int m_count;
};
#endif
Shelf.cpp
#include "Shelf.h"
Shelf::Shelf()
{
m_count = 0;
m_books.resize(0);
}
Shelf::~Shelf()
{
for (unsigned i = 0; i < m_books.size(); ++i)
delete m_books[i];
}
/* Méthodes d'ajout / suppression des livres */
id Shelf::addBook(Book* book)
{
m_books.push_back(book);
return m_count++;
}
id Shelf::addBook(Author author, std::string title, std::string type)
{
m_books.push_back(new Book(m_count, author, title, type));
return m_count++;
}
int Shelf::removeBook(Book* book)
{
for (unsigned i = 0; i < m_books.size(); ++i)
if (book == m_books[i])
{
m_books.erase(m_books.begin() + i);
return 0;
}
return -1;
}
int Shelf::removeBook(id i)
{
if (i > static_cast<int>(m_books.size()))
return -1;
m_books.erase(m_books.begin() + i);
return 0;
}
/* Méthodes d'affichage des livres */
/* Affiche tous les livres */
void Shelf::show(void)
{
for (unsigned i = 0; i < m_books.size(); ++i)
m_books[i]->show();
}
/* Affiche un livre */
int Shelf::showOne(id i)
{
if (i > static_cast<int>(m_books.size()))
return -1;
m_books[i]->show();
return 0;
}
/* Affiche tous les livres d'un auteur */
int Shelf::showByAuthor(Author author)
{
int showed = 0;
for (unsigned i = 0; i < m_books.size(); ++i)
if (m_books[i]->author() == author)
{
m_books[i]->show();
showed++;
}
return showed;
}
/* Affiche tous les livres d'un certain genre */
int Shelf::showByType(std::string type)
{
int showed = 0;
for (unsigned i = 0; i < m_books.size(); ++i)
if (m_books[i]->type() == type)
{
m_books[i]->show();
showed++;
}
return showed;
}
/* Retourne un pointeur vers le livre portant l'id passé en paramètre */
Book* Shelf::book(id i)
{
if (i > static_cast<int>(m_books.size()))
return NULL;
return m_books[i];
}
/* Retourne le nombre de livres -1 */
id Shelf::currentId(void)
{
return m_count;
}
MemberList.h
#ifndef MEMBER_LIST_H_INCLUDED
#define MEMBER_LIST_H_INCLUDED
#include <vector>
#include "main.h"
#include "Member.h"
class MemberList
{
public :
MemberList();
~MemberList();
id addMember(Member*);
id addMember(std::string,std::string);
Member* member(id);
int size(void);
void show(void);
private :
std::vector<Member*> m_members;
unsigned int m_count;
};
#endif
MemberList.cpp
#include "MemberList.h"
MemberList::MemberList()
{
m_count = 0;
}
MemberList::~MemberList()
{
m_members.clear();
}
id MemberList::addMember(Member* member)
{
m_members.push_back(member);
return m_count++;
}
id MemberList::addMember(std::string firstName, std::string surname)
{
m_members.push_back(new Member(m_count, firstName, surname));
return m_count++;
}
Member* MemberList::member(id i)
{
if (i > static_cast<int>(m_members.size()))
return NULL;
return m_members[i];
}
int MemberList::size(void)
{
return m_members.size();
}
void MemberList::show(void)
{
for (unsigned i = 0; i < m_members.size(); ++i)
m_members[i]->show();
}
Library.h
#ifndef LIBRARY_H_INCLUDED
#define LIBRARY_H_INCLUDED
#include <fstream>
#include "Shelf.h"
#include "MemberList.h"
#include "Book.h"
class Library
{
public :
Library();
~Library();
int menu(void);
private :
void load(void);
void loadBooks(void);
void loadMembers(void);
void save(void);
void saveBooks(void);
void saveMembers(void);
/* Menu des livres */
void booksMenu(void);
void addBook(void);
void chooseBookToEdit(void);
void editBook(int);
void editBook(std::string);
void editBook(Author);
void removeBook(void);
void showBooks(void);
/* Menu des membres */
void membersMenu(void);
void addMember(void);
void memberInfo(void);
void memberId(unsigned int);
void loanBookMenu(unsigned int);
void loanBook(unsigned int, unsigned int);
void restoreBook(unsigned int);
void editMember(unsigned int);
void showMembers(void);
/* Méthodes qui demandent des informations à l'utilisateur */
Author getAuthor(void);
std::string getInfo(std::string);
unsigned int getBookId(void);
unsigned int getMemberId(void);
bool confirm(std::string);
Shelf* m_shelf; // Etagère
MemberList* m_members; // Liste des membres
/* Flux de lecture/sauvegarde */
std::ifstream* m_loadBooks;
std::ifstream* m_loadMembers;
std::ofstream* m_saveBooks;
std::ofstream* m_saveMembers;
bool saved;
};
#endif
J'ai ensuite décidé de diviser les méthodes de la classe Library (je ne sais pas si c'est une pratique courante...). En tout cas c'est bien mieux ainsi pour s'y repérer.
Library.cpp
#include <iostream>
#include "Library.h"
Library::Library()
{
m_shelf = new Shelf();
m_members = new MemberList();
}
Library::~Library()
{
delete m_shelf;
delete m_members;
delete m_loadBooks;
delete m_loadMembers;
delete m_saveBooks;
delete m_saveMembers;
}
/* Menu général (boucle principale du programme) */
int Library::menu(void)
{
Library::load();
int choice;
while (1)
{
std::cout << std::endl
<< "Choose an action " << std::endl
<< std::endl
<< " 1- Books menu" << std::endl
<< " 2- Members menu" << std::endl
<< " 3- Save" << std::endl
<< " 4- Quit" << std::endl
<< "--> ";
std::cin >> choice;
if (choice < 1 || choice > 4)
{
std::cout << std::endl << "Invalid choice" << std::endl;
continue;
}
if (choice == 1)
Library::booksMenu();
else if (choice == 2)
Library::membersMenu();
else if (choice == 3)
Library::save();
else
break;
}
return 0;
}
LibraryLoad.cpp
/*
Méthodes de chargement des données de la classe Library
*/
#include <iostream>
#include "Library.h"
void Library::load(void)
{
Library::loadBooks();
Library::loadMembers();
}
void Library::loadMembers(void)
{
m_loadMembers = new std::ifstream("member.txt", std::ios::in);
if (m_loadMembers->fail())
{
std::cerr << "Base de données des membres introuvable" << std::endl;
return;
}
int nbMembers;
*m_loadMembers >> nbMembers;
/* Chargement des données des membres */
int i = 0;
int nbLoan, idLoan;
std::string firstName, surname;
std::cout << "Loaded members " << i << " of " << nbMembers << std::endl;
while (i != nbMembers)
{
/* Nom, prénom, nombre d'emprunts */
*m_loadMembers >> firstName >> surname >> nbLoan;
m_members->addMember(firstName, surname);
/* Identifiants des livres empruntés et recherche du Book* correspondant */
for (int j = 0; j < nbLoan; ++j)
{
*m_loadMembers >> idLoan;
m_members->member(i)->addLoan(m_shelf->book(idLoan));
}
i++;
std::cout << " " << i << " of " << nbMembers << std::endl;
}
std::cout << std::endl;
m_loadMembers->close();
}
void Library::loadBooks(void)
{
m_loadBooks = new std::ifstream("book.txt", std::ios::in);
if (m_loadBooks->fail())
{
std::cerr << "Base de données des livres introuvable" << std::endl;
return;
}
int nbBooks;
*m_loadBooks >> nbBooks;
/* Chargement des données des livres */
int i = 0;
std::string title = "", author1, author2, type;
std::string wordTitle;
int idLoaner = 0;
std::cout << "Loaded books " << i << " of " << nbBooks << std::endl;
while (i != nbBooks)
{
/* Données de base (auteur, titre, genre) */
/* Lecture du titre */
wordTitle = "";
title = "";
*m_loadBooks >> wordTitle;
while (wordTitle != "endOfTitle")
{
title += wordTitle + " ";
wordTitle = "";
*m_loadBooks >> wordTitle;
}
/* Lecture de l'auteur et du type */
*m_loadBooks >> author1 >> author2 >> type;
Author a;
a.firstName = author1;
a.surname = author2;
m_shelf->addBook(a,title,type);
/* id de l'emprunteur du livre (-1 s'il n'y en a pas) */
*m_loadBooks >> idLoaner;
m_shelf->book(i)->loan(idLoaner);
i++;
std::cout << " " << i << " of " << nbBooks << std::endl;
}
m_loadBooks->close();
}
LibrarySave.cpp
/*
Méthodes de sauvegarde des données de la classe Library
*/
#include <iostream>
#include "Library.h"
void Library::save(void)
{
Library::saveBooks();
Library::saveMembers();
}
void Library::saveBooks(void)
{
m_saveBooks = new std::ofstream("book.txt", std::ios::out | std::ios::trunc);
if (m_saveBooks->fail())
{
std::cerr << "Base de données des livres introuvable... Sauvegarde annulée" << std::endl;
return;
}
*m_saveBooks << m_shelf->currentId() << "\n";
/* Boucle de sauvegarde de chaque livre */
std::cout << "Saved books 0 of " << m_shelf->currentId() << std::endl;
for (int i = 0; i < m_shelf->currentId(); ++i)
{
*m_saveBooks << m_shelf->book(i)->title() << " endOfTitle "
<< m_shelf->book(i)->authorFirstName() << " "
<< m_shelf->book(i)->authorSurname() << " "
<< m_shelf->book(i)->type() << " "
<< m_shelf->book(i)->idLoaner() << " \n";
std::cout << " " << i << " of " << m_shelf->currentId() << std::endl;
}
std::cout << std::endl << "Books saved successfully." << std::endl;
m_saveBooks->close();
}
void Library::saveMembers(void)
{
m_saveMembers = new std::ofstream("member.txt", std::ios::out | std::ios::trunc);
if (m_saveMembers->fail())
{
std::cerr << "Base de données des membres introuvable... Sauvegarde annulée" << std::endl;
return;
}
std::cout << "Saved members 0 of " << m_shelf->currentId() << std::endl;
*m_saveMembers << m_members->size() << "\n";
/* Boucle de sauvegarde de chaque membre */
for (int i = 0; i < m_members->size(); ++i)
{
*m_saveMembers << m_members->member(i)->firstName() << " "
<< m_members->member(i)->surname() << " "
<< m_members->member(i)->nbLoan() << " ";
for (unsigned int j = 0; j < m_members->member(i)->nbLoan(); ++j)
*m_saveMembers << m_members->member(i)->book(j)->getId() << " ";
std::cout << " " << i+1 << " of " << m_shelf->currentId() << std::endl;
*m_saveMembers << "\n";
}
std::cout << std::endl << "Members saved successfully." << std::endl;
m_saveMembers->close();
}
LibraryBookMenu
/*
Méthodes du menu des livres de la classe Library
*/
#include <iostream>
#include "Library.h"
void Library::booksMenu(void)
{
int choice;
while(1)
{
std::cout << std::endl
<< std::endl
<< " 1- Add a book" << std::endl
<< " 2- Edit a book" << std::endl
<< " 3- Remove a book" << std::endl
<< " 4- Show" << std::endl
<< " 5- Return" << std::endl
<< "--> ";
std::cin >> choice;
if (choice < 1 || choice > 5)
{
std::cout << std::endl << "Invalid choice" << std::endl;
continue;
}
if (choice == 1)
Library::addBook();
else if (choice == 2)
Library::chooseBookToEdit();
else if (choice == 3)
Library::removeBook();
else if (choice == 4)
Library::showBooks();
else
return;
}
}
void Library::addBook(void)
{
std::string title = Library::getInfo("Title ? --> ");
std::string type = Library::getInfo("Type ? --> ");
m_shelf->addBook(Library::getAuthor(),title, type);
}
/* Menu d'édition des données des livres */
void Library::chooseBookToEdit(void)
{
int choice;
while(1)
{
std::cout << std::endl
<< "Edit book..."
<< std::endl
<< " 1- With id..." << std::endl
<< " 2- With author" << std::endl
<< " 3- With type" << std::endl
<< " 4- Return" << std::endl
<< "--> ";
std::cin >> choice;
if (choice < 1 || choice > 4)
{
std::cout << std::endl << "Invalid choice" << std::endl;
continue;
}
if (choice == 1)
Library::editBook(Library::getBookId());
else if (choice == 2)
Library::editBook(Library::getAuthor());
else if (choice == 3)
Library::editBook(Library::getInfo("Type ? --> "));
else
return;
}
}
/* Permet de changer n'importe quelle information sur le livre portant l'id passé en paramètre */
void Library::editBook(int i)
{
int choice;
while(1)
{
std::cout << std::endl
<< std::endl
<< " 1- Edit all" << std::endl
<< " 2- Edit author" << std::endl
<< " 3- Edit title" << std::endl
<< " 4- Edit type" << std::endl
<< " 5- Return" << std::endl
<< "--> ";
std::cin >> choice;
if (choice < 1 || choice > 5)
{
std::cout << std::endl << "Invalid choice" << std::endl;
continue;
}
if (choice == 1)
{
m_shelf->book(i)->editTitle(Library::getInfo("Title ? --> "));
m_shelf->book(i)->editAuthor(Library::getAuthor());
m_shelf->book(i)->editType(Library::getInfo("Type ? --> "));
}
else if (choice == 2)
m_shelf->book(i)->editAuthor(Library::getAuthor());
else if (choice == 3)
m_shelf->book(i)->editTitle(Library::getInfo("Title ? --> "));
else if (choice == 4)
m_shelf->book(i)->editType(Library::getInfo("Type ? --> "));
else
return;
}
}
/* Remplace un genre par un autre */
void Library::editBook(std::string type)
{
int count = 0;
std::vector<int> idBook(0);
for (int i = 0; i < m_shelf->currentId(); ++i)
if (m_shelf->book(i)->type() == type)
{
count++;
idBook.push_back(i);
}
std::cout << std::endl
<< count << " Books selected." << std::endl
<< "Choose a new type :" << std::endl
<< std::endl;
for (unsigned i = 0; i < idBook.size(); ++i)
m_shelf->book(idBook[i])->editType(Library::getInfo("Type ? --> "));
}
/* Remplace un nom d'auteur par un autre sur tous ses livres */
void Library::editBook(Author author)
{
int count = 0;
std::vector<int> idBook(0);
for (int i = 0; i < m_shelf->currentId(); ++i)
if (m_shelf->book(i)->author() == author)
{
count++;
idBook.push_back(i);
}
std::cout << std::endl
<< count << " Books selected." << std::endl
<< "Choose a new author :" << std::endl
<< std::endl;
Author a = Library::getAuthor();
for (unsigned i = 0; i < idBook.size(); ++i)
m_shelf->book(idBook[i])->editAuthor(a);
}
void Library::removeBook(void)
{
std::string choice;
int id = Library::getBookId();
m_shelf->book(id)->show();
if (Library::confirm("Are yous sure to delete this book ?"));
m_shelf->removeBook(id);
}
void Library::showBooks(void)
{
m_shelf->show();
}
LibraryMemberMenu.cpp
/*
Méthodes du menu des membres de la classe Library
*/
#include <iostream>
#include "Library.h"
void Library::membersMenu(void)
{
int choice;
while(1)
{
std::cout << std::endl
<< std::endl
<< " 1- Add a member" << std::endl
<< " 2- Member..." << std::endl
<< " 3- Show" << std::endl
<< " 4- Return" << std::endl
<< "--> ";
std::cin >> choice;
if (choice < 1 || choice > 7)
{
std::cout << std::endl << "Invalid choice" << std::endl;
continue;
}
if (choice == 1)
Library::addMember();
else if (choice == 2)
Library::memberInfo();
else if (choice == 3)
Library::showMembers();
else
return;
}
}
void Library::addMember(void)
{
std::string firstName = Library::getInfo("First Name ? --> ");
std::string surname = Library::getInfo("Surame ? --> ");
m_members->addMember(firstName, surname);
}
/* Méthode qui permet de se rendre au menu d'un membre */
void Library::memberInfo(void)
{
int choice;
while(1)
{
std::cout << std::endl
<< std::endl
<< "Search by..." << std::endl
<< " 1- Id" << std::endl
<< " 2- Surname" << std::endl
<< " 3- Return" << std::endl
<< "--> ";
std::cin >> choice;
if (choice < 1 || choice > 3)
{
std::cout << std::endl << "Invalid Choice" << std::endl;
continue;
}
if (choice == 1)
Library::memberId(Library::getMemberId());
else if (choice == 2)
{
std::vector<unsigned int> idMembers(0);
std::string surname = Library::getInfo("\nSurname ? --> ");
for (int i = 0; i < m_members->size(); ++i)
if (m_members->member(i)->surname() == surname)
idMembers.push_back(i);
}
else
return;
}
}
/* Menu d'un membre */
void Library::memberId(unsigned int i)
{
m_members->member(i)->show();
int choice;
while(1)
{
std::cout << std::endl
<< std::endl
<< " 1- Loan" << std::endl
<< " 2- Restore" << std::endl
<< " 3- Edit" << std::endl
<< " 4- Return" << std::endl
<< "--> " << std::endl;
std::cin >> choice;
if (choice < 1 || choice > 4)
{
std::cout << std::endl << "Invalid Choice" << std::endl;
continue;
}
if (choice == 1)
Library::loanBookMenu(i);
else if (choice == 2)
Library::restoreBook(i);
else if (choice == 3)
Library::editMember(i);
else
return;
}
}
/* Menu d'emprunt */
void Library::loanBookMenu(unsigned int idMember)
{
int choice;
while(1)
{
std::cout << std::endl
<< std::endl
<< "Choose a book..." << std::endl
<< " 1- With Id" << std::endl
<< " 2- Search by Title" << std::endl
<< " 3- Search by Author" << std::endl
<< " 4- Search by Type" << std::endl
<< " 5- Return" << std::endl
<< "--> ";
std::cin >> choice;
if (choice < 1 || choice > 5)
{
std::cout << std::endl << "Invalid choice" << std::endl;
continue;
}
if (choice == 1)
Library::loanBook(idMember,Library::getBookId());
else if (choice == 2)
{
std::string title = Library::getInfo("Title ? --> ");
for (int i = 0; i < m_shelf->currentId(); ++i)
if (m_shelf->book(i)->title() == title)
Library::loanBook(idMember,i);
}
else if (choice == 3)
{
Author author = Library::getAuthor();
for (int i = 0; i < m_shelf->currentId(); ++i)
if (m_shelf->book(i)->author() == author)
Library::loanBook(idMember,i);
}
else if (choice == 4)
{
std::string type = Library::getInfo("Type ? --> ");
for (int i = 0; i < m_shelf->currentId(); ++i)
if (m_shelf->book(i)->type() == type)
Library::loanBook(idMember,i);
}
else
return;
}
}
void Library::loanBook(unsigned int idMember, unsigned int idBook)
{
m_shelf->book(idBook)->show();
if (Library::confirm("Are you sure to loan this book ?"))
m_shelf->book(idBook)->loan(idMember);
}
void Library::restoreBook(unsigned int i)
{
/* A faire !! */
}
void Library::editMember(unsigned int i)
{
std::string firstName = Library::getInfo("First Name ? --> ");
std::string surname = Library::getInfo("Surname ? --> ");
m_members->member(i)->edit(m_members->member(i)->getId(), firstName, surname);
}
void Library::showMembers(void)
{
m_members->show();
}
LibraryGet.cpp
/*
Méthodes de la classe Library qui demandent des informations à l'utilisateur
Les noms de fonction sont assez explicites et se passent de commentaires.
*/
#include <iostream>
#include "Library.h"
std::string Library::getInfo(std::string msg)
{
std::string info;
std::cout << std::endl << msg;
std::cin >> info;
std::cout << std::endl;
return info;
}
Author Library::getAuthor(void)
{
Author a;
a.firstName = Library::getInfo("Author's First Name ? --> ");
a.surname = Library::getInfo("Author's Surname ? --> ");
return a;
}
unsigned int Library::getBookId(void)
{
int id;
do
{
std::cout << std::endl << "Id ? --> ";
std::cin >> id;
if (id > m_shelf->currentId())
std::cout << std::endl << "Unknow book (maximum ID is" << m_shelf->currentId() << ")" << std::endl;
}while (id > m_shelf->currentId());
return id;
}
unsigned int Library::getMemberId(void)
{
int id;
do
{
std::cout << std::endl << "Id ? --> ";
std::cin >> id;
if (id > m_members->size())
std::cout << std::endl << "Unknow member (maximum ID is" << m_members->size() << ")" << std::endl;
}while(id > m_members->size());
return id;
}
bool Library::confirm(std::string msg)
{
std::string choice;
do
{
std::cout << std::endl << msg << " Yes/No --> ";
std::cin >> choice;
if (choice != "Yes" && choice != "yes" && choice != "No" && choice != "no")
std::cout << std::endl << "Invalid choice (anwsers are 'Yes' and 'No')" << std::endl;
}
while (choice != "Yes" && choice != "yes" && choice != "No" && choice != "no");
if (choice == "Yes" || choice == "yes")
return true;
return false;
}
Voila ! J'essaierai de mettre les sources en ligne ainsi que l'exécutable.
Edit : J'oubliais une petite bdd pour tester tout ça.
book.txt
5
Attaque au couteau endOfTitle Patrick Carat Philosophy 1
Trenne de Lariat Ixpross endOfTitle Agathe Chris Romance 5
Herry Petter endOfTitle Jk Ralling Novel 3
Plice endOfTitle Hercol Poriot Sci_Fi 1
Chevalier Emerida endOfTitle Anna Corbillard Unknown 2
a- pas mal de résidus du C:
- des void entre parenthèses (pas grave),
- des retours d'int au lieu de bool/exceptions qui sont plus adaptés en C++ -- je n'ai pas cherché à vérifier si les retours étaient systématiquement testé.
- des typedef désuets
b- le passage des chaines coute cher => référence constante (je pense que le tuto en parle ; à vérifier)
c- dans le main, inutile de créer la Library sur le tas vu comme elle est utilisée.
d- main.h est un choix de nom de fichier peu équivoque ; de plus il traitre d'Author
e- destructeurs inutiles vu que tous les membres des objets sont "trivialement" destructibles.
f- le préfixe "edit" me perturbe, surtout pour un setter.
De plus, vu qu'il s'agit de classes de données, tout exposer à coup de setter+getter me gêne -> toute encapsulation est de toute façon rompue.
g- getter non const-correct
i- attention, les Book sont copiables ; est-ce vraiment ce que tu veux ? Ne s'agit-il pas d'entités ?
(j'image que cela s'applique aussi à d'autres des classes)
j- m_here ne me parle pas. Serait-ce un m_is_not_being_borrowed ?
k- tu es sûr que l'on dit "restore" quand on rend des livres en anglais ?
l- m_loans.clear() est inutile : c'est implicite. Même commentaire pour le destructeur qui sera à préférer en version générée par défaut par le compilo.
m- pour le removeXXX, fait plutôt un find. Voire, utilise directement vector::remove
Ceci dit, en vrai, on aurait plutôt une liste d'ids (!= indices) et non de pointeurs. Ne serait-ce que pour faciliter la sérialisation.
n- le type des tailles, c'est size_t plutôt qu'unsigned
o- Plein d'indices qui voyagent. Joue avec les itérateurs plutôt.
p- Le destructeur de library détruit des trucs qui ne sont pas mis dans un état non invalide dans le constructeur. => kaboum possible.
D'ailleurs je vois plein de flux qui existent en permanence, et gérés via pointeurs. C'est un gros code smell en ce qui me concerne.
Localise!
Merci beaucoup pour tous ces commentaires, ça fait plaisir (même si jusqu'a 'p' ça fait beaucoup ).
Je vais tenter de les appliquer pour améliorer mon code, mais surtout ma manière de programmer en C++.
Merci.
Juste une question toutefois, sur les destructeurs (remarques 'e' et 'l') : Je préfère quand même que ça soit explicite et bien tout écrire pour savoir bien ou je vais et ce que je fais, donc est-ce que c'est grave si je garde ma version des destructeurs ?
Ce que tu peux faire, c'est de mettre un commentaire pour dire "OK, il n'y a pas de destructeur, mais c'est normal : celui que va me générer le compilo sera meilleur que tous ceux que je pourrais écrire"
Ok merci, je vais éditer mon code précédent après avoir appliqué point par point tes remarques (même si je ne sais pas encore comment je vais faire pour ne pas "briser" l'encapsulation (remarque f), mais je me débrouillerai).
Ce point là, c'est celui sur lequel j'ai passé le moins de temps, et probablement le moins trivial de tous.
Tu es en situation où tu manipules des données, et non pas où tu as des entités qui offrent de véritables services.
Ça à permis de réduire concidérablement le nombre de ligne, mais c'est à peu près tout.
Si quelqu'un a une remarque à faire, c'est la première fois que j'utilise les templates, j'aurais aimé avoir un retour s'il vous plaie :/
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles- ♡ Copying is an act of love.
× 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.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.