MVC (headers + class): erreur dans mon code c++
Résolu/FerméJLesage Messages postés 33 Date d'inscription mercredi 14 novembre 2012 Statut Membre Dernière intervention 23 février 2024 - 8 nov. 2023 à 17:23
- Symantec class 3 secure server ca v20.0.0.6
- Picasa 3 - Télécharger - Albums photo
- Ps3 media server - Télécharger - Divers Réseau & Wi-Fi
- Scp server - Forum Jeux vidéo
- Site sans 3d secure forum - Forum Réseaux sociaux
- Nvcontainer windows class - Forum Carte graphique
4 réponses
4 nov. 2023 à 01:29
@[Dal] StatutContributeur, tu as raison. Merci pour la remarque. Voici le contenu de Controller_Personne.h:
#ifndef CONTROLLER_PERSONNE_H #define CONTROLLER_PERSONNE_H #include "Model_Personne.h" #include "View_Personne.h" #include <string> class Controller_Personne { public: Controller_Personne(Model_Personne unePersonne, View_Personne uneVuePersonne); virtual ~Controller_Personne(); Model_Personne personne; View_Personne vue; //Setters void setPrenom(std::string unPrenom); void setNom(std::string unNom); void setProfession(std::string uneProfession); void setAge(int unAge); //Getters std::string getPrenom(); std::string getNom(); std::string getProfession(); int getAge(); void getAffichage(); protected: private: }; #endif // CONTROLLER_PERSONNE_H
Modifié le 6 nov. 2023 à 22:10
Bonjour,
Avant, tout essaye dans tes prochains message de poster un exemple minimal qui permet de reproduire ton problème. Ici tu dis avoir trois problèmes, ce devrait donc, une fois minimisés, donner trois fils de discussion.
Il y a plusieurs choses qui ne vont pas.
- Si tu appelles le constructeurs par défaut, pas besoin d'ajouter () :
ViewPersonne uneVuePersonne;
- Tes constructeurs ne sont pas correctement écrits. Cela devrait plutôt ressembler à :
Model_Personne::Model_Personne( std::string prenom, std::string nom, std::string profession, int age ): prenom(prenom), nom(nom), profession(profession), age(age) {}
- Note que dans une telle situation, le corps du constructeur est vide, on peut donc le déporter intégralement dans le header.
- Le type de l'âge n'est pas cohérent partout (parfois int, parfois std::string), du coup le linker ne parvient pas à retrouver ses billes.
- La signature de ControllerPersonne n'est pas cohérente à la déclaration et à l'appel
- Là où tu utilises std::cout, tu devrais inclure <iostream>
- La fonction main devrait retourner un entier (le code d'exécution, 0 si tout va bien, un code d'erreur documenté sinon)
Par ailleurs, un certain nombre d'améliorations pourraient être apportées :
- Plutôt que passer les paramètres par recopie, tu devrais les passer autant que possible par référence (voir const référence), cela serait plus efficace.
- Tes signatures de fonctions devraient indiquer quels paramètres restent constant (avec le mot clé const). Si this est maintenu constant, il faut aussi ajouter const derrière la parenthèse fermante du prototype.
class Controller_Personne { private: std::string prenom public: std::string getPrenom() const; } std::string Controller_Personne getPrenom() const { return prenom; }
- Tu peux sous-entendre this-> quand il n'y a pas d’ambiguïté, cela allège le code. Mais dans un setter par exemple il peut être nécessaire, par exemple pour écrire :
void ModelPersonne::setNom(std::string nom) { this->nom = nom; }
Exemple :
- Il ne sert à rien d'ouvrir plusieurs fois std::cout, autant le faire en une instruction.
- Pour alléger le code, si tu es dans un ".cpp", tu peux parfaitement utiliser using namespace std; ou mieux, using std::cout; using std::endl; (voir ici). Par contre il ne faut jamais le faire dans un ".hpp"
- Généralement, on adopte soit le style camel case, soit tout en minuscules avec des _ (comme dans le kernel linux), mais les deux à la fois c'est bizarre. Tant qu'on est dans le nommage, ce serait pas mal d'adopter un style tout en français, ou mieux, tout en anglais.
class VoitureDeSport { VoitureDeSport(){} }; int main() { VoitureDeSport voitureDeSport(); return 0; }
class voiture_de_sport_t { voiture_de_sport_t(){} }; int main() { voiture_de_sport_t voiture_de_sport(); return 0; }
- On peut légèrement optimiser le code en ajoutant le mot clé inline devant les fonctions courtes dans le ".hpp" (mais pas dans le .cpp). Concrètement, le compilateur substitue l'appel par le corps de la fonction. Cela concerne typiquement les getters et les setters.
- Dans le cas des fonctions inline, on peut considérablement alléger l'implémentation des fonctions inline en déportant le corps de leurs fonctions dans le ".hpp". Cependant, seul le corps des fonctions inline peut ainsi être déporté.
- Si une classe ne comporte que des attributs et méthodes publiques, autant utiliser directement une structure (qui en C++, peut parfaitement avoir des méthodes).
- Déclarer un destructeur (virtuel) n'est pas nécessaire si la classe n'est pas virtuelle. Tu peux les sous-entendre si tu ne fais rien dedans (ce qui est ton cas). Par contre, une classe virtuelle impose la déclaration d'un destructeur virtuel.
- La classe ViewPersonne a un intérêt assez limité, vu qu'elle ne stocke rien.
- Pour plus de lisibilité, je trouve mieux de déclarer les attributs (souvent privés) avant les méthodes. Cela permet de se faire une idée de la taille d'une instance en mémoire. Mais là c'est plus une affaire de goût.
- La méthode getAffichage est mal nommée, elle suggère qu'on récupère un objet affichage. Il serait mieux de le renommer afficherPersonne pour être cohérent avec le reste du code.
- Essaye de faire tenir tes lignes en moins de 80 caractères, quitte à passer à la ligne. Pense à mettre des espaces autour des espaces. Autant de facteurs qui améliorent la lisibilité.
Une fois toutes ces remarques appliquées (je n'ai juste pas fait les using std::cout; et using std::endl;) qui ne plaisent pas à tout le monde on obtient :
// ViewPersonne.hpp #ifndef VIEW_PERSONNE_H #define VIEW_PERSONNE_H #include <string> struct ViewPersonne { ViewPersonne() {} void afficherPersonne( std::string prenom, std::string nom, std::string profession, int age ) const; }; #endif // VIEW_PERSONNE_H // ModelPersonne.hpp #ifndef MODEL_PERSONNE_H #define MODEL_PERSONNE_H #include <string> class ModelPersonne { private: std::string prenom; std::string nom; std::string profession; int age; public: ModelPersonne( std::string unPrenom, std::string unNom, std::string uneProfession, int unAge ): prenom(unPrenom), nom(unNom), profession(uneProfession), age(unAge) {} virtual ~ModelPersonne() {} // Setters inline void setPrenom(std::string prenom) { this->prenom = prenom; } inline void setNom(std::string nom) { this->nom = nom; } inline void setProfession(std::string profession) { this->profession = profession; } inline void setAge(int age) { this->age = age; } // Getters inline std::string getPrenom() const { return prenom; } inline std::string getNom() const { return nom; } inline std::string getProfession() const { return profession; } inline int getAge() const { return age; } }; #endif // MODEL_PERSONNE_H // ControllerPersonne.hpp #ifndef CONTROLLER_PERSONNE_H #define CONTROLLER_PERSONNE_H #include <string> class ControllerPersonne { private: ModelPersonne personne; ViewPersonne vue; public: ControllerPersonne( ModelPersonne personne, ViewPersonne vue ): personne(personne), vue(vue) {} // Setters inline void setPrenom(std::string prenom) { personne.setPrenom(prenom); } inline void setNom(std::string nom) { personne.setNom(nom); } inline void setProfession(std::string profession) { personne.setProfession(profession); } inline void setAge(int age) { personne.setAge(age); } // Getters inline std::string getPrenom() const { return personne.getPrenom(); } inline std::string getNom() const { return personne.getNom(); } inline std::string getProfession() const { return personne.getProfession(); } inline int getAge() const { return personne.getAge(); } void afficherPersonne() const; }; #endif // CONTROLLER_PERSONNE_H // ViewPersonne.cpp #include <string> #include <iostream> void ViewPersonne::afficherPersonne( std::string unPrenom, std::string unNom, std::string uneProfession, int unAge ) const { std::cout << "Prénom: " << unPrenom << std::endl << "Nom: " << unNom << std::endl << "Profession: " << uneProfession << std::endl << "Âge: " << unAge << std::endl; } // ControllerPersonne.cpp void ControllerPersonne::afficherPersonne() const { vue.afficherPersonne( personne.getPrenom(), personne.getNom(), personne.getProfession(), personne.getAge() ); } // main.cpp #include <string> int main(){ ModelPersonne unePersonne( "Jacques", "Baeur", "Artiste-Informaticien", 36 ); ViewPersonne uneVuePersonne; //(); ControllerPersonne unControlleurPersonne( unePersonne, uneVuePersonne ); unControlleurPersonne.afficherPersonne(); return 0; }
Bonne chance
8 nov. 2023 à 17:23
Merci pour les remarques très pertinentes, @mamiemando StatutModérateur . J'ai appris de nouvelles choses grâce à votre commentaire.
3 nov. 2023 à 15:33
Salut JLesage,
Je pense que tu n'as pas posté le contenu de Controller_Personne.h et que tu as posté à la place celui de Controller_Personne.c
Modifié le 6 nov. 2023 à 21:08
J’ai les erreurs suivants dans mon code (je les ai numéroté parce qu’il y en a 3):
error 1: no matching function for call to ‘Model_Personne::Model_Personne()’;
error 2: no matching function for call to ‘Controller_Personne::Controller_Personne(Model_Personne&, View_Personne (&)())’;
error 3: no declaration matches ‘void View_Personne::afficherPersonne(std::string, std::string, std::string, std::string)’