Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Erreur] Héritage POO

Problème rencontré avec le cours

Sujet résolu
Anonyme
    22 juin 2015 à 21:32:38

    Bonjour,

    je viens demander de l'aide pour le cours deC++.

    Tout d'abord, voici le code :

    main.cpp

    #include <iostream>
    #include "Personnage.h"
    
    using namespace std;
    
    int main()
    {
        Personnage monPersonnage;
        Guerrier monGuerrier;
    
        monPersonnage.coupDePoing(monGuerrier);
        monGuerrier.coupDePoing(monPersonnage);
    
        return 0;
    }
    

    Personnage.cpp

    #include "Personnage.h"
    
    using namespace std;
    
    Personnage::Personnage () : m_vie(100), m_nom("Jack")
    {
        // Rien à écrire
    }
    
    void Personnage::recevoirDegats(int degats)
    {
        m_vie -= degats;
    }
    
    void Personnage::coupDePoint(Personnage &cible) const
    {
        cible.recevoirDegats(10);
    }
    

    Personnage.h

    #ifndef PERSONNAGE_H_INCLUDED
    #define PERSONNAGE_H_INCLUDED
    
    #include <iostream>
    #include <string>
    
    class Personnage
    {
        // Méthodes
        public:
    
        Personnage();
        void recevoirDegats(int degats);
        void coupDePoint(Personnage &cible) const;
    
        // Attributs
        private:
    
        int m_vie;
        std::string m_nom;
    };
    
    #endif // PERSONNAGE_H_INCLUDED
    

    Guerrier.cpp

    #include "Guerrier.h"
    
    void Guerrier::frapperCommeUnSourdAvecUnMarteau() const
    {
        // Rien
    }
    

    Guerrier.h

    #ifndef GUERRIER_H_INCLUDED
    #define GUERRIER_H_INCLUDED
    
    #include <iostream>
    #include <string>
    #include "Personnage.h"
    
    class Guerrier : public Personnage
    {
        // Méthodes
        public:
    
        void frapperCommeUnSourdAvecUnMarteau() const;
    
    };
    
    #endif // GUERRIER_H_INCLUDED
    

    Et voilà les erreurs de compilations en capture d'écran :




    Pourtant, dans le cours, il est dit que, même s'il y a une erreur, la compilation devrait marché (l'erreur est justement à corriger dans la suite du cours), une erreur que le compilateur accepterait. J'ai pourtant essayé de régler l'erreur par tout les moyens mais je n'y arrive.

    Et, s'il vous plaît, pas de réponse du genre "Alors ça veut dire que le compilateur n'accepte pas l'erreur", car ce n'est pas une erreur correspondant au log de compilation.

    Au revoir et j'espère avoir vite une réponse merci d'avance ! ;)

    • Partager sur Facebook
    • Partager sur Twitter
      22 juin 2015 à 21:39:22

      Salut,

      C'est pourtant marqué dessus, comme le port salut :"Guerrier was not declared in this scope" !!! Et c'est normal :

      Tu inclus ton fichier d'en-tête personnage.h dans ton fichier main.cpp.  Le compilateur ne connait donc, lorsqu'il parcour la fonction main(), que la classe Personnage et aucune autre.  Il ne faut donc pas s'étonner s'il se plaint de ne pas connaitre la classe Guerrier (qui est définie dans le fichier d'en-tête guerrier.h) ;)

      -
      Edité par koala01 22 juin 2015 à 21:39:40

      • Partager sur Facebook
      • Partager sur Twitter
      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
      Anonyme
        22 juin 2015 à 22:21:40

        Euh... merci pour t'as réponse mais si tu relis le code demain.cpp tu verras que j'ai bien inclus l'en-tête :

        #include "Personnage.h"

        Mais merci quand même d'avoir essayé. ;)

        J'espère que quelqu'un pourra résoudre mon problème.

        -
        Edité par Anonyme 22 juin 2015 à 22:22:48

        • Partager sur Facebook
        • Partager sur Twitter
          22 juin 2015 à 22:23:17

          Tu le fais exprès ou bien ?

          Au passage, renomme Personnage::coupDePoint en Personnage::coupDePoing.

          • Partager sur Facebook
          • Partager sur Twitter
            22 juin 2015 à 22:25:47

            1) Ton compilateur de donne ton erreur : il te suffit de la lire et de faire l'effort de l'interpréter pour la corriger.

            2) koala01 fait l'effort de te traduire en français ce que te dis ton compilateur, et tu ne fais pas non plus l'effort de comprendre ce qu'il écrit.

            Bref, pour progresser d'une étape, tu dois vraiment apprendre à faire l'effort de lire et comprendre les infos qu'on te donne. Souviens toi que ton compilateur est ton meilleur ami en toutes circonstances ! ;)

            -
            Edité par Faellan 22 juin 2015 à 22:26:55

            • Partager sur Facebook
            • Partager sur Twitter
            Bla bla bla
              22 juin 2015 à 22:27:46

              Il faut tout simplement marquer cela dans main.cpp . ( au cas ou tu n'aurais pas compris ;) )

              #include "Guerrier.h"



              -
              Edité par charlescol 22 juin 2015 à 22:29:06

              • Partager sur Facebook
              • Partager sur Twitter
                22 juin 2015 à 22:29:11

                charlescol a écrit:

                Il faut tout simplement marquer cela dans main.cpp :

                #include "Guerrier.h"



                Et voici comment en 2s il ne retiendra rien de cette histoire... :-°

                • Partager sur Facebook
                • Partager sur Twitter
                Bla bla bla
                Anonyme
                  22 juin 2015 à 22:34:58

                  Désolé c'est une erreur de lecture de ma part mais le commentaires de koala aurait pu être mieux formuler, en tout cas, vraiment merci et j'essaye de lire les erreur du compilo mais je n'ai pas trouvé même en prenant en compte ce qu'il y avait écrit.

                  Enfin, bref, merci beaucoup et au revoir. :D

                  P.S. : par contre le "coupDePoing" est, je crois, une erreur du site.

                  -
                  Edité par Anonyme 22 juin 2015 à 22:37:12

                  • Partager sur Facebook
                  • Partager sur Twitter
                    23 juin 2015 à 1:49:04

                    Lel_06. a écrit:

                    Désolé c'est une erreur de lecture de ma part mais le commentaires de koala aurait pu être mieux formuler, en tout cas, vraiment merci et j'essaye de lire les erreur du compilo mais je n'ai pas trouvé même en prenant en compte ce qu'il y avait écrit.

                    Attends, tu te fous de moi ???

                    Je prend la peine de rappler l'erreur que ton compilateur te donne (Geurrier n'est pas connu dans le scope), et de te dire que ca arrive dans la fonction main() avant de t'indiquer que, lorsque ton compilateur commence à s'intéresser à la fonction main, il ne connais pas la classe guerrier...

                    Si tu avais un tout petit peu lu ce qu je t'ai écris, tu te serais rendu compte que je ne parlais que du fichier main.cpp (qui est le fichier dans lequel arrive l'erreur), et tu n'aurais pas commencé à aller chercher dans un fichier cpp différent!!!

                    Alors, histoire que tu comprennes bien le principe (c'est vrai, il m'arrive de l'expliquer, visiblement... j'aurais du le faire) :

                    Lorsque le compilateur travaille sur un fichier d'implémentation (ceux qui ont l'extension *.cpp; par exemple main.cpp), il va faire exactement comme toi lorsqu tu lis un livre : il va le lire de la première ligne de la première page à la dernière ligne de la dernière page, APRES AVOIR OUBLIE TOUT CE QU'IL A PU RENCONTRER DANS LE FICHIER QU'IL VIENT DE TERMINER DE TRAITER; ce qui fait que, lorsqu'il est à la ligne 10 d'un fichier .cpp, il ne connait de ce fichier que les 9 premières lignes et N'A AUCUNE IDEE DE CE QUI SE PASSE A LA LIGNE 12.

                    La seule chose qu'il connait, (à part ce qui se trouve dans le fichier sur lequel il travail), c'est le contenu des fichiers pour lesquels il a croisé une directive #include (je simplifie, afin que tu ne me dises pas que c'est "trop compliqué").  S'il a rencontré une la directive #include "personnage.h", il connait aussi le contenu du fichier personnage.h, mais rien d'autre.

                    Du coup, lorsqu'il arrive à la ligne 9 fichier main.cpp, il n'a jamais croisé quoi que ce soit qui ait trait à la classe Guerrier.  Et, comme il ne sait donc pas ce qu'il doit faire, il adopte la seule réaction "cohérent" : il t'envoie bouller en disant qu'il ne sait pas du tout ce qu'est le mot Guerrier.

                    Tu as compris, maintenant, c'était assez explicite ????

                    • Partager sur Facebook
                    • Partager sur Twitter
                    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
                      23 juin 2015 à 11:24:41

                      Lel_06. a écrit:

                      P.S. : par contre le "coupDePoing" est, je crois, une erreur du site.

                      point != poing. Il y a beaucoup d'erreurs dans le cours mais la plupart d'entre elles concernent le langage C++, pas le français.

                      -
                      Edité par Ksass`Peuk 23 juin 2015 à 11:47:04

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                      Anonyme
                        23 juin 2015 à 18:29:21

                        Bon, je tiens à m'excuser pour l'erreur d'orthographe de ma part, mais pas le peine de me "crier" dessus car je n'ai que 13 ans et qu'à mon âge, les fautes d'orthographes, ça se fait encore.

                        Je suis désolé d'avoir dit ce que je penser de ton commentaire pour ne pas être focus koala, mais tu aurai pu être plus clair.

                        Et je ne trouve pas qu'il y est des erreurs de C++ sur ce site personnellement. :colere2:

                        • Partager sur Facebook
                        • Partager sur Twitter
                          23 juin 2015 à 18:39:42

                          Et voila comment un sujet peut déraper... SVP : Que personne ne prenne compte de cette remarque : Lel_06 a écrit : >Et je ne trouve pas qu'il y est des erreurs de C++ sur ce site personnellement. :colere2:

                          Personnellement, je trouve que @Koala01 s'est très bien exprimé...

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Anonyme
                            23 juin 2015 à 18:54:45

                            Chacun son avis sur ce cours.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              23 juin 2015 à 18:57:37

                              Lel_06. a écrit:

                              Et je ne trouve pas qu'il y est des erreurs de C++ sur ce site personnellement. :colere2:

                              Ben en fait, si on prend le code que tu as actuellement et qui est grosso-modo tiré du cours du site. Il y a plusieurs erreurs de conception dans les classes proposées.

                              D'abord, quand on a une classe comme un Personnage, ou de manière générale tout élément qui est une entité au sens "un élément qui a une identité propre, et dont on veut garantir l'unicité", on dit qu'il a une sémantique d'entité. Et dans ce cas, la première chose que l'on doit faire, c'est interdire la copie et l'affectation d'un tel élément. Or le cours ne le fait pas, et même pire ! Il les utilise ! C'est une très mauvaise pratique de conception.

                              Dans la même veine, c'est aussi le cas d'une classe comme une Arme. Et de la même façon, on n'interdit pas la copie et l'affectation.

                              Au passage, on fait de la gestion manuelle de la mémoire. Or en C++, on ne veut surtout pas gérer manuellement la mémoire (ni aucune autre ressource allouée dynamiquement : fichiers, mutex, sockets, ...) manuellement parce que du fait de la présence d'exception, c'est bien trop compliqué à faire correctement, et pour un débutant, appréhender cette gestion est juste impossible.

                              C++ propose une mécanique bien plus fiable qui est le RAII (Resource Allocation Is Initialization) et son pendant inverse qui nous garantit que tout objet alloué sur la pile appellera son destructeur, le résultat c'est que dans un bon code C++, on trouvera très rarement le mot-clé "new" et jamais le mot clé "delete" tout en ayant une gestion bien plus robuste des ressources. Or cette mécanique qui permet d'avoir des codes robustes et simples n'est pas abordée du tout par le cours.

                              Finalement, on utiliserait jamais une hiérarchie de classe pour définir quelque chose qui ressemble à un RPG, mais ça, à la limite, à fin d'exercice, ça peut passer.

                              -
                              Edité par Ksass`Peuk 23 juin 2015 à 19:02:49

                              • Partager sur Facebook
                              • Partager sur Twitter

                              Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                              Anonyme
                                23 juin 2015 à 19:02:47

                                Ce sont peut-être des erreurs pour toi, mais, à mon avis, si elle sont dans ce cours, elle n'y sont pas pour rien. Je pense que c'est juste une manière différente de coder enC++.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  23 juin 2015 à 19:08:00

                                  Lel_06. a écrit:

                                  Ce sont peut-être des erreurs pour toi, mais, à mon avis, si elle sont dans ce cours, elle n'y sont pas pour rien.

                                  Effectivement, elles y sont parce que ce code a été écrit à l'origine par une personne qui n'y connaissait pas grand chose en C++ (et qui n'a pas écrit de C++ depuis très longtemps), puis patché par une personne qui travaille principalement en C++ de l'âge de pierre. Mais un langage ça évolue, beaucoup.

                                  Si écrire du code rigide et instable est, pour toi, une autre manière de coder en C++, admettons. Tu t'en boufferas les doigts le moment venu.

                                  Mais ce code est buggé que tu le veuilles ou non :

                                  vector<Vehicule*> listeVehicules;
                                  
                                  
                                  listeVehicules.push_back(new Voiture(15000, 5));
                                  //J'ajoute à ma collection de véhicules une voiture
                                  //Valant 15000 euros et ayant 5 portes
                                  listeVehicules.push_back(new Voiture(12000, 3));  //…
                                  listeVehicules.push_back(new Moto(2000, 212.5));

                                  Et il est tiré du cours.

                                  -
                                  Edité par Ksass`Peuk 23 juin 2015 à 19:12:37

                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                                  Anonyme
                                    23 juin 2015 à 19:18:07

                                    Ksass`Peuk a écrit:

                                    Lel_06. a écrit:

                                    Ce sont peut-être des erreurs pour toi, mais, à mon avis, si elle sont dans ce cours, elle n'y sont pas pour rien.

                                    Effectivement, elles y sont parce que ce code a été écrit à l'origine par une personne qui n'y connaissait pas grand chose en C++ (et qui n'a pas écrit de C++ depuis très longtemps), puis patché par une personne qui travaille principalement en C++ de l'âge de pierre. Mais un langage ça évolue, beaucoup.

                                    Si écrire du code rigide et instable est, pour toi, une autre manière de coder en C++, admettons. Tu t'en boufferas les doigts le moment venu.

                                    Mais ce code est buggé que tu le veuilles ou non :

                                    vector<Vehicule*> listeVehicules;
                                    
                                    
                                    listeVehicules.push_back(new Voiture(15000, 5));
                                    //J'ajoute à ma collection de véhicules une voiture
                                    //Valant 15000 euros et ayant 5 portes
                                    listeVehicules.push_back(new Voiture(12000, 3));  //…
                                    listeVehicules.push_back(new Moto(2000, 212.5));

                                    Et il est tiré du cours.

                                    -
                                    Edité par Ksass`Peuk il y a 2 minutes


                                    Alors déjà, les personnes qui ont rédigé le cours et qu'ils ont améliorer s'y connaissent (je pense) mieux que toi et le code que tu m'as présenté ne m'a pas l'air buggé.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      23 juin 2015 à 19:38:08

                                      Lel_06. a écrit:

                                      Alors déjà, les personnes qui ont rédigé le cours et qu'ils ont améliorer s'y connaissent (je pense) mieux que toi

                                      Merci pour la blague :) . Je fais de la preuve de programme C et C++, je connais vaguement le sujet.

                                      Lel_06. a écrit:

                                      et le code que tu m'as présenté ne m'a pas l'air buggé.

                                      Il y a 6 chemins d'exécution dans ce programme qui peuvent conduire à une erreur dans ces trois lignes, et 3 peuvent entraîner la fuite de mémoire.

                                      vector<Vehicule*> listeVehicules;
                                       
                                      listeVehicules.push_back(new Voiture(15000, 5));
                                      //             ^(1)      ^(2)
                                      listeVehicules.push_back(new Voiture(12000, 3));
                                      //             ^(3)      ^(4)
                                      listeVehicules.push_back(new Moto(2000, 212.5));
                                      //             ^(5)      ^(6)
                                      

                                      (1) Si le push_back échoue, on jette une exception, l'allocation (2) est alors nécessairement perdue.

                                      (3) Si le push_back échoue, on jette une exception, l'allocation (4) est alors nécessairement perdue.

                                      (5) Si le push_back échoue, on jette une exception, l'allocation (6) est alors nécessairement perdue.

                                      En plus, comme ici, on ne fait pas le traitement immédiat de l'erreur (ce qui en soit n'est pas excessivement grave, on n'a pas forcément envie de la traiter), les destructions qui sont plus loin dans le même morceau de code :

                                      for(int i(0); i<listeVehicules.size(); ++i)
                                      {
                                        delete listeVehicules[i];  //On libère la i-ème case mémoire allouée
                                        listeVehicules[i] = 0;  //On met le pointeur à 0 pour éviter les soucis
                                      }

                                      ne seront pas effectuées si on a une exception qui est lancée. Donc si c'est en (3), on perd aussi (2), et si c'est en (5), on perd aussi (2) et (4). Entre ces deux morceaux de code, on trouve des affichages qui sont eux aussi sources d'exceptions, donc s'ils échouent, on perd (2), (4) et (6).

                                      Le plantage du programme peut être un comportement normal (si on n'a plus de RAM, le plantage est acceptable), en revanche, le fait que le programme ne soit pas auto-suffisant pour la libération des ressources n'est pas vraiment acceptable formellement. La seule raison pour laquelle la machine ne perd pas de mémoire est que l'OS est assez malin pour nettoyer le bordel qu'aura mis le programme en plantant sans rien nettoyer.

                                      En C++, à la place de cela :

                                      int main(){
                                        vector<Vehicule*> listeVehicules;
                                      
                                        listeVehicules.push_back(new Voiture(15000, 5));
                                        listeVehicules.push_back(new Voiture(12000, 3));
                                        listeVehicules.push_back(new Moto(2000, 212.5));  
                                      
                                      
                                        listeVehicules[0]->affiche();
                                        listeVehicules[2]->affiche();
                                      
                                        for(int i(0); i<listeVehicules.size(); ++i)
                                        {
                                          delete listeVehicules[i];
                                          listeVehicules[i] = 0;
                                        }
                                      
                                        return 0;
                                      }

                                      On peut écrire ceci :

                                      int main(){
                                        vector<unique_ptr<Vehicule>> listeVehicules;
                                      
                                        listeVehicules.push_back(make_unique<Voiture>(15000, 5));
                                        listeVehicules.push_back(make_unique<Voiture>(12000, 3));
                                        listeVehicules.push_back(make_unique<Moto>(2000, 212.5));  
                                      
                                      
                                        listeVehicules[0]->affiche();
                                        listeVehicules[2]->affiche();
                                      }

                                      Dans ce code, on a plus besoin de gérer la mémoire, et dans le même temps en cas d'erreur, le programme aura la politesse de nettoyer tout son bazar avant de planter.

                                      -
                                      Edité par Ksass`Peuk 23 juin 2015 à 19:52:37

                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                                        23 juin 2015 à 19:52:40

                                        Lel_06. a écrit:

                                        Ksass`Peuk a écrit:


                                        Mais ce code est buggé que tu le veuilles ou non :

                                        vector<Vehicule*> listeVehicules;
                                        
                                        
                                        listeVehicules.push_back(new Voiture(15000, 5));
                                        //J'ajoute à ma collection de véhicules une voiture
                                        //Valant 15000 euros et ayant 5 portes
                                        listeVehicules.push_back(new Voiture(12000, 3));  //…
                                        listeVehicules.push_back(new Moto(2000, 212.5));

                                        Et il est tiré du cours.

                                        -
                                        Edité par Ksass`Peuk il y a 2 minutes


                                        Alors déjà, les personnes qui ont rédigé le cours et qu'ils ont améliorer s'y connaissent (je pense) mieux que toi et le code que tu m'as présenté ne m'a pas l'air buggé.


                                        Justement, il est buggé, pour une raison bien simple : une allocation dynamique de la mémoire peut toujours échouer et provoque le lancement d'une exception.

                                        Or, quand une exception est lancée, on "brise le flux d'exécution classique" et on remonte la pile d'appel jusuqu'à ce que le l'on crois (en fonction des circonstances) un bloc try catch qui puisse récupérer l'exception qui a été lancée ou (dans le pire des cas), juqu'au plantage pure et simple de l'application.

                                        Ainsi, si le push_back de la ligne 8 échoue, tu te retrouve avec les deux premières voitures créées pour lesquelles tu n'a absolument plus aucun moyen de récupérer un pointeur (vu qu'on est en dehors de la portée dans laquelle listevehicule est accessible), et cela occasionne systématiquement une fuite mémoire.

                                        Voilà en quoi un tel code est buggé.  Malheureusement, tu n'as pas encore assez d'expérience ni assez de recul pour t'en rendre compte.

                                        Mais c'est normal : tu es en phase d'apprentissage, et on ne peut donc pas te demander de strictement tout savoir!

                                        Le problème, c'est que tu t'imagines qu'il n'y a que des gamins de ton age sur ce forum. Or, au risque d'en oublier, il faut savoir que Ksass`peuk, bacela, lghm, gbdivers et moi même sont des développeurs professionnels.  A titre personnel, cela fait plus de dix ans que je m'intéresse au C++ et, au risque de dévoiler un secret, lghm est un architecte logiciel qui travaille dans une boite renommée.

                                        Ne va donc pas croire que l'on ne sait pas de quoi l'on parle : c'est totalement faux.  La plupart de ceux que j'ai cité sont intervenus sur des projets dont tu n'as absolument aucune idée et don le seul nombre de fichiers pourrait te faire tourner la tête!!!

                                        Maintenant, le cours de C++ tel qu'il est présenté sur ce site correspond à peu près à la manière dont on envisageait le C++ au début des années 2000.  C'est, effectivement, de cette manière que certains d'entre-nous ont appris le C++ à l'époque.  Et je peux t'assurer que nous avons morflé, car peu de gens n'avaient suffisamment de recul pour nous indiquer nos erreurs.

                                        Tu as la chance d'être arrivé (beaucoup) plus tard dans le développement, d'avoir des gens qui ont eu l'occasion de comprendre les problèmes auxquels ils étaient confrontés (et auxquels tu seras forcément confronté si tu t'obstines dans cette voie) et qui sont capables de repérer des problèmes potentiels avant même qu'il ne prennent réellement forme.

                                        De plus, ces personnes savent exactement par quoi tu va passer et ont un recul suffisant pour te proposer "une autre approche", plus "moderne", mais surtout plus sécurisante et plus robuste de faire les choses.

                                        Alors, dis moi maintenant... Entre l'auteur d'un cours que tu ne croisera sans doute jamais sur le forum et des professionnels qui savent de quoi ils parlent et qui mettent les mains dans le cambouis tous les jours, qui sera le plus digne de confiance à ton gout ?

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        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
                                          23 juin 2015 à 19:57:57

                                          Ca ne sert à rien de lui répondre, il n'est même pas capable de se remettre en cause pour une simple faute d'orthographe :

                                          Lel_06. a écrit :

                                          P.S. : par contre le "coupDePoing" est, je crois, une erreur du site.

                                          Sinon, @Ksass' Peuk à part en cas de manque de RAM, quels peuvent être les autres raisons d'échec d'un push_back()? Peuvent-elles être toutes déterminées ou certaines sont en quelques sortes aléatoire ? Et "à quelle fréquence" se produise-t-elle (probabilité) ?

                                          -
                                          Edité par Bouli1515 23 juin 2015 à 19:59:54

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            23 juin 2015 à 20:04:15

                                            Le manque de mémoire, c'est la raison qui est due au fonctionnement de la fonction push_back() avec l'allocateur par défaut fournit par l'implémentation de std::vector. Que reste-t-il ? D'abord les exceptions que pourrait lancer l'opérateur de copie du type stocké, ensuite, si l'utilisateur a redéfinit l'allocateur, il peut avoir des mécanismes qui produisent des exceptions.

                                            Pour ce qui est de la fréquence, faut mesurer ^^ .

                                            -
                                            Edité par Ksass`Peuk 23 juin 2015 à 20:04:45

                                            • Partager sur Facebook
                                            • Partager sur Twitter

                                            Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                                              23 juin 2015 à 20:13:22

                                              Bouli1515 a écrit:

                                              Ca ne sert à rien de lui répondre, il n'est même pas capable de se remettre en cause pour une simple faute d'orthographe :

                                              Lel_06. a écrit :

                                              P.S. : par contre le "coupDePoing" est, je crois, une erreur du site.

                                              Sinon, **@KsassPeuk** à part en cas de manque de RAM, quels peuvent être les autres raisons d'échec d'unpush_back()`? Peuvent-elles être toutes déterminées ou certaines sont en quelques sortes aléatoire ? Et "à quelle fréquence" se produise-t-elle (probabilité) ?


                                              Le problème, c'est que un code comme
                                              tab.push_back(new MACHIN(/* ... */));

                                              risque d'occasionner au moins deux allocations dynamiques successives :

                                              une allocation dynamique pour MACHIN (pour lequel on n'a d'ailleurs aucune garantie qu'il n'y aura pas d'autres allocation dynamiques pour certains membres en "sous main") et un allocation dynamique dont le but est d'obtenir un espace mémoire capable de représenter l'ensemble des éléments que le tableau doit contenir.

                                              S'il n'y avait que l'allocation dynamique de l'espace mémoire nécessaire pour représenter l'ensemble des éléments du tableau, la probabilité (sur un système supportant une charge "légère" à "moyenne") pour que cette seule allocation dynamique échoue serait, effectivement, relativement limitée (du moins, tant que le nombre d'élément à représenter reste relativement limité).

                                              Mais il y a aussi le fait que new MACHIN peut échouer et cette probabilité va essentiellement dépendre du type de l'objet que l'on essaye de créer et de la manière dont on récupère les données qui permettent de le faire.

                                              Par exemple, si le constructeur de MACHIN doit utiliser des informations de connexion à une base de données pour obtenir les données qui l'intéresse et que, pas de bol, la connection est inactive, le constructeur ne saura pas faire son job, et la seule solution qu'il aura sera de lancer une exception :p

                                              De même, si le constructeur de MACHIN doit contenir l'ensemble de l'encyclopédie universelle sous la forme d'une seule chaine de caractères (ou sous la forme d'un tableau de chaine de caractères), ben on ne peut pas garantir que le système trouvera assez d'espace mémoire pour représenter toutes ces données.  Et, bien sur, les exemples sont légions ;)

                                              Quoi qu'il en soit, la seule chose qui importe, c'est de savoir que le système peut parfaitement dire "non, je ne te donne pas l'espace mémoire que tu as demandé" et que, si cela arrive, il y a une exception qui sera lancée.

                                              On peut estimer que cela n'arrivera très certainement pas tous les jours (la "probabilité" que cela arrive reste malgré tout relativement mince), mais ce n'est pas une raison pour basculer dans le monde des bisounours et de se dire que "bah, de toutes manières, cela n'arrivera jamais" ;)

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                              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
                                                23 juin 2015 à 20:14:09

                                                Mais alors, le fonctionnement d'un push_backest "en gros", si il n'a y plus de place dans le tableau, on copie tout dans un autre tableau plus grand ? Donc les classe à sémantiques d'entité, où l'on a supprimé le constructeur par copie, ne peuvent pas être stocké dedans ? Voilà pourquoi sur cppreference c'est marqué que le vecteur ne stocke que les objets copy-assignable ! Je viens de comprendre (je crois). Merci @Ksass`Peuk !

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  23 juin 2015 à 20:20:39

                                                  Bouli1515 a écrit:

                                                  Mais alors, le fonctionnement d'un push_backest "en gros", si il n'a y plus de place dans le tableau, on copie tout dans un autre tableau plus grand ?

                                                  Oui, mais il faut bien le mettre quelque part... et "dans l'air du temps" n'est pas un endroit safe :P...

                                                  Tu devra donc mettre le contenu du tableau "en mémoire" et là, tu subit les restrictions du système et qui est limité (en gros) à sa mémmoire RAM et à sa quantité de mémoire "virtuelle" (swap) ;)

                                                  Donc les classe à sémantiques d'entité, où l'on a supprimé le constructeur par copie, ne peuvent pas être stocké dedans ? Voilà pourquoi sur cppreference c'est marqué que le vecteur ne stocke que les objets copy-assignable ! Je viens de comprendre (je crois).
                                                  Merci @Ksass`Peuk !

                                                  C'est la raison pour laquelle on stocke des pointeurs (qui ne sont que des valeurs numériques entières représentant une adresse mémoire) dans les collections (et que l'on essayera dans la mesure du possible de s'assurer que la mémoire sera détruite en temps opportun au travers de l'utilisation de pointeurs intelligents ;) )

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                  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
                                                    23 juin 2015 à 20:29:50

                                                    Merci à toi aussi @Koala01 ! Mais qu'entends-tu exactement par :

                                                    Koala01 a écrit :

                                                    Oui, mais il faut bien le mettre quelque part... et "dans l'air du temps" n'est pas un endroit safe :p ... >Tu devra donc mettre le contenu du tableau "en mémoire" et là, tu subit les restrictions du système et qui est limité (en gros) à sa mémoire RAM et à sa >quantité de mémoire "virtuelle" (swap) ;)

                                                    Le vecteur ne créé-t-il pas un autre tableau dans lequel il copie tous ses éléments PUIS supprime le premier tableau ?

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      23 juin 2015 à 20:38:30

                                                      Bouli1515 a écrit:

                                                      Merci à toi aussi @Koala01 !
                                                      Mais qu'entends-tu exactement par :

                                                      Koala01 a écrit :

                                                      Oui, mais il faut bien le mettre quelque part... et "dans l'air du temps" n'est pas un endroit safe :p ...
                                                      Tu devra donc mettre le contenu du tableau "en mémoire" et là, tu subit les restrictions du système et qui est limité (en gros) à sa mémoire RAM et à sa >quantité de mémoire "virtuelle" (swap) ;)

                                                      Le vecteur ne créé-t-il pas un autre tableau dans lequel il copie tous ses éléments PUIS supprime le premier tableau ?


                                                      Oui, bien, sur, mais ou va-t-il créer le tableau de "copie" et d'où vient le "premier tableau" selon toi ?

                                                      Tu peux essayer de les placer "dans le vent", de les faire porter par des nuages, mais ce sera beaucoup plus efficace si tu les place dans une quantité de mémoire qui appartient au système sur lequel les données sont utilisée ;)

                                                      Or, la quantité de mémoire dont un système donné dispose est forcément limitée : il y a la RAM (on ne rajoute pas de la ram tous les jours sur les pc :D) et la mémoire "virtuelle" qui trouve généralement place sur un disque dur (pagefile sous windows, partition swap sous linux).  Mais, même si on peut définir beaucoup de mémoire "swap" de la sorte, nous serons quand même toujours bel et bien limité quant à l'espace que l'on peut créer (ne serait-ce qu'à l'espace disponible sur le disque dur :P)

                                                      Et comme c'est le système d'exploitation qui détermine la quantité de mémoire dont ton application peut disposer, la bonne question devient : quand le système d'exploitation estimera que mon application a "assez de mémoire" et refusera de m'en donner d'avantage.

                                                      Jusqu'à il n'y a pas si longtemps, le système d'exploitation (sous windows) refusait par exemple de donner plus de 2Gb de mémoire au total à n'importe quelle application...  Si tu voulais disposer d'avantage de données, du devais veiller à "faire de la place" ;)

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                      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
                                                        23 juin 2015 à 20:51:41

                                                        Merci encore @Koala01 pour tes précieuses explications ! Pour rebondir sur ta dernière phrase :

                                                        Koala01 a écrit :

                                                        Jusqu'à il n'y a pas si longtemps, le système d'exploitation (sous windows) refusait par exemple de donner plus de 2Gb de mémoire au total à n'importe > quelle application...

                                                        Il n'y a pas aussi des solutions du type : aller dans les paramètres de l'OS pour augmenter la mémoire allouée à une application.

                                                        En ce qui concerne la différence emplace_back/push_back:

                                                        • Le premier n'alloue de la mémoire que si c'est nécessaire,
                                                        • Alors que le second le fait systématiquement ?
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          23 juin 2015 à 21:01:40

                                                          Bouli1515 a écrit:

                                                          Merci encore @Koala01 pour tes précieuses explications !
                                                          Pour rebondir sur ta dernière phrase :

                                                          Koala01 a écrit :

                                                          Jusqu'à il n'y a pas si longtemps, le système d'exploitation (sous windows) refusait par exemple de donner plus de 2Gb de mémoire au total à n'importe > quelle application...

                                                          Il n'y a pas aussi des solutions du type : aller dans les paramètres de l'OS pour augmenter la mémoire allouée à une application.

                                                          Cela dépendait encore du système d'exploitation ;)

                                                          En ce qui concerne la différence emplace_back/push_back:

                                                          • Le premier n'alloue de la mémoire que si c'est nécessaire,
                                                          • Alors que le second le fait systématiquement ?

                                                          Tout dépend de quelle allocation dynamique tu parles, à vrai dire :p

                                                          Car, si on parle de l'espace mémoire nécessaire pour représenter les différents éléments d'un tableau, emplace (et consors) et push_back agissent exactement de la même manière : s'il n'y a pas assez d'espace pour rajouter un élément, on augmente la taille de la mémoire qui les maintient (pas forcément de 1 ;) ) pour pouvoir rajouter l'élément.

                                                          Par contre, push_back occasionnera automatiquement une copie de l'élément que l'on ajoute, alors que emplace va essayer (autant que possible) d'utiliser la sémantique de mouvement (et donc d'éviter une copie inutile), ne "retombant" sur la copie "classique" que si la copie par déplacement est impossible (comme c'est prévu par la norme ;) )

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                          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
                                                            23 juin 2015 à 21:08:11

                                                            Merci encore pour tes réponses @Koala01, je pense que j'en ai finis pour ce soir :p ! En C++11/14, il est préférable d'utiliser emplace_backà la place de push_backcar celui-ci est à la fois (un peu) plus performant et plus safe ! Mais sa fonction est similaire à celle de push_back. Bonne nuit et A++ ! ;)

                                                            -
                                                            Edité par Bouli1515 23 juin 2015 à 21:08:59

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                            Anonyme
                                                              24 juin 2015 à 13:12:33

                                                              Je ne me suis pas embêter à trop lire c'est long commentaire étant donné que c'est juste pour dire "Lel_06 change de cours" et les justifications qui vont avec.

                                                              Et pour...

                                                              Bouli1515 a écrit:

                                                              Ca ne sert à rien de lui répondre, il n'est même pas capable de se remettre en cause pour une simple faute d'orthographe :

                                                              Lel_06. a écrit :

                                                              P.S. : par contre le "coupDePoing" est, je crois, une erreur du site.

                                                              Sinon, @Ksass' Peuk à part en cas de manque de RAM, quels peuvent être les autres raisons d'échec d'un push_back()? Peuvent-elles être toutes déterminées ou certaines sont en quelques sortes aléatoire ? Et "à quelle fréquence" se produise-t-elle (probabilité) ?

                                                              -
                                                              Edité par Bouli1515 il y a environ 17 heures


                                                              Je me suis remis en question plus tard lorsque j'ai compris ma faute alors ce n'est pas la peine de rager, j'ai l'impression d'être moins énervé que vous alors que je n'ai que 13 ans, qu'est-ce que cela veut dire, vous n'êtes donc pas mature ?
                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              [Erreur] Héritage POO

                                                              × 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.
                                                              • Editeur
                                                              • Markdown