IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

std::map et fuite de memoire


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 8
    Points : 6
    Points
    6
    Par défaut std::map et fuite de memoire
    Bonjour,

    j'ai cree une map contenant un pointeur vers un objet.

    std::map<const char*,Sprite*> m_mapSprite;
    std::map<const char*,Sprite*>::iterator seIterator;

    1 - lorsque j'utilise la methode erase d'une map, est ce que cette methode appelle le destructeur de sprite?

    2 - J'ai pu lire dans la faq consacre au stl que pour un vecteur, il fallait detruire le pointeur sur l'objet car un pointeur n'est pas un objet.
    Je suppose que c'est la meme chose pour une map mais j'aimerais en etre sur.

    3 - voila ce que j'ai fait pour effacer l'element pointe par seIterator a une certaine condition:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    pour chaque element de la map(un for sans incrementation)
       si condition est vrai
          delete seIterator->second;
          m_mapSprite.erase(seIterator++);
       sinon
        seIterator++
    est ce correct?

    quelques remarques:
    -ma map contient en realite des objets derive de Sprite et que Sprite est la classe mere virtuel.
    -Lorsque je debug je vois bien les elements disparaitre de la map. Cependant je ne vois pas clairement la memoire alloue a mon programme baisse ou monte clairement dans le gestionnaire de memoire. c'est ce qui me fait douter

    merci pour votre aide

  2. #2
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    Mis a part la façon de procéder, je ne pense pas que tu leak. Sprite et si lourd que ça que tu veux voir l'impact en mémoire ?
    Un autre façon et de faire des pointeur intelligent, ou du moins en utiliser. Dans ton cas, je pense que auto_ptr suffirait. Sinon, shared_pointer.
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  3. #3
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par zip8000 Voir le message
    Bonjour,

    j'ai cree une map contenant un pointeur vers un objet.

    std::map<const char*,Sprite*> m_mapSprite;
    std::map<const char*,Sprite*>::iterator seIterator;

    1 - lorsque j'utilise la methode erase d'une map, est ce que cette methode appelle le destructeur de sprite?

    2 - J'ai pu lire dans la faq consacre au stl que pour un vecteur, il fallait detruire le pointeur sur l'objet car un pointeur n'est pas un objet.
    Je suppose que c'est la meme chose pour une map mais j'aimerais en etre sur.

    3 - voila ce que j'ai fait pour effacer l'element pointe par seIterator a une certaine condition:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    pour chaque element de la map(un for sans incrementation)
       si condition est vrai
          delete seIterator->second;
          m_mapSprite.erase(seIterator++);
       sinon
        seIterator++
    est ce correct?

    quelques remarques:
    -ma map contient en realite des objets derive de Sprite et que Sprite est la classe mere virtuel.
    -Lorsque je debug je vois bien les elements disparaitre de la map. Cependant je ne vois pas clairement la memoire alloue a mon programme baisse ou monte clairement dans le gestionnaire de memoire. c'est ce qui me fait douter

    merci pour votre aide
    1 - Non, il faut utiliser delete. Erase efface le pointeur de la map, c'est tout.
    2 - Bien sur qu'il faut libérer aussi pour la map.
    3 - Non c'est faux, voir dans la FAQ : http://cpp.developpez.com/faq/cpp/in...ssion_elements

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    pour chaque element de la map(un for sans incrementation)
       si condition est vrai
          delete seIterator->second;
          seIterator = m_mapSprite.erase(seIterator);
       sinon
        seIterator++
    Si tu n'as pas besoin de performances hallucinantes (et encore ça se discute), je te conseille fortement comme dit précédemment d'utiliser des pointeurs intelligents.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Une petite précision quand même: un pointeur est réellement un objet. Simplement, c'est un objet de type numérique entier non signé qui contient... l'adresse mémoire à laquelle on trouvera l'instance de l'objet du type indiqué (qui est l'objet qui nous intéresse).

    Lorsqu'une collection de pointeurs est détruite, les pointeurs sont bels et bien détruits, mais ce sont les objets pointés qui ne le sont pas.

    Ceci dit, Tu pourrais déjà t'éviter bien des soucis en utilisant la classe string, disponible dans l'espace de noms std par inclusion du fichier d'en-tête standard <string> en lieu et place de ton pointeur char * représentant une chaine "C style" comme clé pour ta map.

    Mais, en effet, si tu prend la décision de créer un objet en utilisant l'allocation dynamique (new ou new[]), tu prend également la responsabilité de la destruction dynamique (avec delete ou delete[]) de cette objet au moment opportun.

    Maintenant, toute la question à se poser est
    Quand sera-t-il opportun de détruire l'objet pointé
    Et tu n'as pas vraiment de règle établie pour répondre à cette question, car, en effet, deux solutions s'offrent principalement à toi:

    Soit c'est l'objet qui contient la collection de pointeurs (ici, la std::map) qui va prendre la resonsabilité de la libération de la mémoire assignée au pointeur.

    Dans ce cas, tu dois, effectivement veiller à appeler delete sur l'objet représenté par l'itéarateur avant de perdre l'itérateur en question.

    Soit la responsabilité de la libération de la mémoire incombe "à quelque chose d'autre".

    Dans ce cas, l'objet contenant ta collection (ici ta std::map) sera simplement avisé que la mémoire assignée à un pointeur donné a été libérée.

    Evidemment, dans ce cas, il te suffit simplement de retirer l'objet de la collection, sans tenter de libérer une deuxième fois la mémoire assignée au pointeur.

    La première solution prendrait une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    class MaClass
    {
        /* j'utilise des entiers pour représenter la clé de la map, mais l'idée
         * est la même quel que soit le type de cette clé ;)
         */
        typedef std::map<int, Object *> map;
        public:
            typedef typename map::iterator iterator;
            typedef typename map::const_iterator const_iterator;
            MaClass(){}
            ~MaClass()
            {
                for(iterator it=items_.begin();it!=items_.end();++it)
                    delete (*it).second;
            }
            void registerItem(Object * obj)
            {
                 int i;
                /* récupération de l'identifiant dans un i */
                items_.insert(std::make_pair(i,obj));
            }
            void destroyItem(int key)
            {
                iterator it= items_.find(key);
                if(it!=items_.end())
                {
                    delete (*it).second;
                    items_.erase(it);
                }
            }
        private:
            map items_;
    }
    La deuxième solution pourrait parfaitement prendre une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    /* la classe contenant la map est un singleton */
    class Singleton
    {
        /* j'utilise des entiers pour représenter la clé de la map, mais l'idée
         * est la même quel que soit le type de cette clé ;)
         */
        typedef std::map<int, Object *> map;
        public:
            typedef typename map::iterator iterator;
            typedef typename map::const_iterator const_iterator;
            static Singleton & instance()
            {
                static Singleton inst;
                return inst;
            }
            void registerItem(Object * obj)
            {
     
                 int i;
                /* récupération de l'identifiant dans un i */
                items_.insert(std::make_pair(i,obj));
            }
            void unRegisterItem(int key)
            {
                iterator it= items_.find(key);
                if(it!=items_.end())
                    items_.erase(it);
            }
        private:
            Singleton(){}
            ~Singleton(){}
    };
    /* la classe qui gère réellement l'objet */
    class MaClass
    {
        public:
            /* NOTA : cela pourrait très bien fonctionner si obj n'était pas
             * un pointeur et était créé de manière classique ;)
             */
            MaClass(int id):obj(new Object(id))
            {
                Singleton::instance().registerItem(obj);
            }
            ~MaClass()
            {
                Singleton::instance().unRegisterItem(obj->id(););
                delete obj;
            }
        private:
            Object * obj;
    };
    Toute la "difficulté" résidant dans le fait de déterminer quelle solution est la moins mauvaise dans ta situation
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 8
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par Lavock Voir le message
    Mis a part la façon de procéder, je ne pense pas que tu leak. Sprite et si lourd que ça que tu veux voir l'impact en mémoire ?
    Un autre façon et de faire des pointeur intelligent, ou du moins en utiliser. Dans ton cas, je pense que auto_ptr suffirait. Sinon, shared_pointer.
    Le programme en lui meme est secondaire. Je m'interesse surtout a appliquer les cours que je lis et surtout les comprendre. Je ne pense pas non plus qu'il y a une fuite de memoire. Simplement je me demandais pourquoi je ne voyais pas de difference notable dans le gestionnaire des taches.
    Basiquement en appuyant sur la touche espace je cree un objet balle(derive de sprite). Ces balles bougent vers le haut de la fenetre et sont detruites lorsqu'elles atteignent le haut de la fenetre et qu'on ne les voit plus.

    j'ai regarde la faq poukill mais ca ne semble pas etre approprie a mon cas car je ne determine pas l'element a supprimer dans ma map par sa cle mais par la position de l'objet. Peut etre qu'utiliser une map dans mon programme est un mauvais choix.

    Une petite précision quand même: un pointeur est réellement un objet.
    merci pour la precision.

    Ceci dit, Tu pourrais déjà t'éviter bien des soucis en utilisant la classe string,
    c'est fait!

    les 2 solutions que tu presentes sont elegantes. Merci. et plus important je les comprends

    Sinon pour que ce soit clair, ma demarche est d'apprendre le polymorphisme,l'heritage, la surcharge d'operateur etc...
    Lorsque j'ai fini le cours, je me suis dit :
    tiens je vais creer une classe sprite
    puis
    tiens je vais creer une classe personnage, une autre ennemi et encore une balle. ces classes heriteront de sprites
    puis
    tiens je vais faire en sorte que chaque classe fille agissent de differentes manieres en fonction des touches clavier: le personnage ira a droite lorsque j'appuie sur la fleche droite, des balles seront creer lorsque j'appuie sur la touche espace etc..(classe virtuelle polymorphisme, dynamic cast etait les notions a apprendre)


    et il me fallait un conteneur pour garder tout ca. j'ai choisi une map...euh honnetement c'etait parce que c'etait l'exemple que j'avais vu. Il faudra que je me trouve un petit explicatif sur l'interet d'utiliser tel ou tel container.

    apres vous avoir lu, j'ai 1 question:
    en quoi mon algo de suppression d'un element est faux? Je rappelle que je ne repere pas l'element a effacer par sa cle mais par la position de l'objet.

    en tout cas merci pour votre aide

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par zip8000 Voir le message
    Le programme en lui meme est secondaire. Je m'interesse surtout a appliquer les cours que je lis et surtout les comprendre. Je ne pense pas non plus qu'il y a une fuite de memoire. Simplement je me demandais pourquoi je ne voyais pas de difference notable dans le gestionnaire des taches.
    Avant d'arriver à voir une différence flagrante dans le gestionnaire de taches si tu crée de petits objets, il te faudra déjà en perdre un nombre important
    Basiquement en appuyant sur la touche espace je cree un objet balle(derive de sprite). Ces balles bougent vers le haut de la fenetre et sont detruites lorsqu'elles atteignent le haut de la fenetre et qu'on ne les voit plus.
    Tu es donc plutot dans la deuxième situation que j'ai donnée: ce serait au gestionnaire de l'affichage de décider de détruire les balles lorsqu'elles sortent de la zone, le gestionnaire de balles en lui-même étant "simplement" là pour... garder une trace des différentes balles existantes...
    j'ai regarde la faq poukill mais ca ne semble pas etre approprie a mon cas car je ne determine pas l'element a supprimer dans ma map par sa cle mais par la position de l'objet. Peut etre qu'utiliser une map dans mon programme est un mauvais choix.
    Visibilement, la map n'est donc peut être pas le container le plus adapté à ton problème

    Un set pourrait éventuellement faire mieux l'affaire, si tu veux les garder trier...
    les 2 solutions que tu presentes sont elegantes. Merci. et plus important je les comprends
    c'est déjà pas si mal
    Sinon pour que ce soit clair, ma demarche est d'apprendre le polymorphisme,l'heritage, la surcharge d'operateur etc...
    voila une démarche bien saine
    Lorsque j'ai fini le cours, je me suis dit :
    tiens je vais creer une classe sprite
    puis
    tiens je vais creer une classe personnage, une autre ennemi et encore une balle. ces classes heriteront de sprites
    puis
    tiens je vais faire en sorte que chaque classe fille agissent de differentes manieres en fonction des touches clavier: le personnage ira a droite lorsque j'appuie sur la fleche droite, des balles seront creer lorsque j'appuie sur la touche espace etc..(classe virtuelle polymorphisme, dynamic cast etait les notions a apprendre)
    N'oublie quand même pas le principe de substitution de liskov dans tout cela...

    Je ne dis pas que tes trois classes ne sont pas des sprites, mais il faudra veiller à... ce que ce soit réellement le cas...

    Dans le cas présent, ce peut être le cas si (et seulement si) la classe sprite ne fait que présenter une interface permettant:
    • un mouvement
    • l'affichage
    Il n'y a, en effet, pas grand chose d'autre qui soit commun à une balle et à un personnage (qu'il soit joueur ou non)
    et il me fallait un conteneur pour garder tout ca. j'ai choisi une map...euh honnetement c'etait parce que c'etait l'exemple que j'avais vu. Il faudra que je me trouve un petit explicatif sur l'interet d'utiliser tel ou tel container.
    Ah, l'éternel problème du choix le plus adapté à la situation...

    Il est à ce point récurrent qu'il existe une entrée dans la FAQ qui permet de se faire une idée... y as-tu jeté un oeil
    apres vous avoir lu, j'ai 1 question:
    en quoi mon algo de suppression d'un element est faux? Je rappelle que je ne repere pas l'element a effacer par sa cle mais par la position de l'objet.
    Le fait est que la std::map est un conteneur qui est particulièrement adapté à la recherche d'élément en fonction d'une clé...

    Si, déjà, tu n'utilise pas cette clé comme principale manière de repérer l'élément qui t'intéresse, tu en perd tous les avantages

    De plus, il ne faut pas oublier la règle de la responsabilité unique:

    Bien souvent, si un objet (ou une fonction) a plus d'une responsabilité, c'est qu'elle en a sans doute trop...

    Le fait de demander à ton gestionnaire de sprites de gérer tout à la fois les sprites existants (créés par ailleurs) et leur destruction "en temps opportun" me semble clairement contrevenir à cette règle parce que cela implique qu'il doit... déterminer le moment opportun pour les détruire
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    Il est pas faux, il est old school. Cela a été abordé ici. [edit] Et puis même remarque que koala aussi !

    Si tu ne vois pas de différence notable, c'est parce qu'une balle pèse à mon avis une centaine d'octet au grand max... Pour une réservation de pile+segment de généralement a peu près 1 ou 2mo min (ça dépend des compilos).

    En plus de ça, il y a les poolers. En gros, un new demande de la mémoire à l'os s'il n'en a plus, et delete ce contente de rendre la mémoire a new. Elle ne sera rendu à l'OS qu'à la fin la plupart du tend. Cela permet de rendre pas trop lent un code du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while (true) {
     ptr = new A[1000];
     //traitement
     delete [] ptr;
    }
    Cela mériterait presque une entrée à la faq ><.
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 8
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Avant d'arriver à voir une différence flagrante dans le gestionnaire de taches si tu crée de petits objets, il te faudra déjà en perdre un nombre important


    Dans le cas présent, ce peut être le cas si (et seulement si) la classe sprite ne fait que présenter une interface permettant:
    • un mouvement
    • l'affichage
    mon sprite est defini avec:
    -une surface SDL(oui je fais du SDL mais je devrais vite aller voir autre chose. )
    -string pour le nom du fichier
    -classe vecteur que j'ai cree(vecteur au sens mathematique)

    sinon:
    constructeur de copie, surcharge de l'operateur =, une fonction virtuel update.

    Tout ca fonctionne comme je le souhaite. Mais bon je me rend compte que ca peut vite devenir tres confus. Il faudra que je remette le nez dans l'UML pour un vrai projet je pense.

    Il est à ce point récurrent qu'il existe une entrée dans la FAQ qui permet de se faire une idée... y as-tu jeté un oeil
    oui j'ai vu ca. mais bon a certaines questions la reponse c'est : "bin euh..". Enfin ca m'a bien fait comprendre que choisir le container approprie etait vraiment important. Je ferais le tour des containers disponible et des interets et inconvenient de chaque quand je pourrais.
    Le fait est que la std::map est un conteneur qui est particulièrement adapté à la recherche d'élément en fonction d'une clé...

    Si, déjà, tu n'utilise pas cette clé comme principale manière de repérer l'élément qui t'intéresse, tu en perd tous les avantages
    c'est ce que je me suis dit. Mais a d'autres endroit j'utilise la cle. Par exemple je commence a reflechir au collision potentiel entre le personnage et les ennemis. La la cle personnage me facilitera la tache. enfin j'espere.
    De plus, il ne faut pas oublier la règle de la responsabilité unique:

    Bien souvent, si un objet (ou une fonction) a plus d'une responsabilité, c'est qu'elle en a sans doute trop...


    Le fait de demander à ton gestionnaire de sprites de gérer tout à la fois les sprites existants (créés par ailleurs) et leur destruction "en temps opportun" me semble clairement contrevenir à cette règle parce que cela implique qu'il doit... déterminer le moment opportun pour les détruire
    mmmh ok...c'est vrai que j'ai quelques soucis de conception. Quand dois je creer les ennemis? comment je les initialise? des questions comme ca. Mais ca touche plus a la conception qu'a la realisation. Pour le moment je m'interesse surtout a ce qui se passe en memoire, a comprendre les syntaxes etc.. bref a apprendre C++.

    grosso modo:j'ai 3 classes: Game, Scene, Sprite
    un Game a une Scene.
    une scene a plusieurs sprite

    Il est pas faux, il est old school. Cela a été abordé ici.
    ah d'accord je comprend mieux ce code maintenant.
    La correction de 2003 a permis d'aligner la méthode erase des map avec celles des autres conteneurs - en renvoyant l'itérateur valide qui suit celui venant d'être tout juste invalidé.
    voila tout est dit. parce que je me demandais a quel moment l'iterator etait incremente. Merci

    bon dans l'ensemble je crois avoir eu toutes les reponses que je voulais. Je met donc ce sujet comme resolu.

    Encore merci

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par zip8000 Voir le message
    mmmh ok...c'est vrai que j'ai quelques soucis de conception. Quand dois je creer les ennemis? comment je les initialise? des questions comme ca. Mais ca touche plus a la conception qu'a la realisation. Pour le moment je m'interesse surtout a ce qui se passe en memoire, a comprendre les syntaxes etc.. bref a apprendre C++
    A vrai dire, la conception *devrait* etre un étape préliminaire à la programmation...

    Et je ne suis vraiment pas de l'avis de ceux qui estiment possible d'apprendre la conception au travers d'un langage.

    En effet, les principes algorithmiques ou les principes de l'OO sont, quelque part, immuables, même si l'on remarque certaines subtilités entre les langages.

    Un langage, ce n'est, en définitive qu'une question de syntaxe et de grammaire...

    Le plus intéressant du travail est, normalement, fait bien avant d'en arriver à écrire ne serait-ce que la première ligne de code, et l'écriture du code pourrait se résumer à "un long et fastidieux travail de traduction"
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    Citation Envoyé par koala01 Voir le message
    A vrai dire, la conception *devrait* etre un étape préliminaire à la programmation...
    C'est là le problème quand on commence : souvent on s'aperçoit des erreurs de conception lors de la programmation. Il est vrai qu'on ne devrait pas revenir sur une bonne conception, mais il est quand même ardue qu'elle soit bonne au première essaie >< !

    @zip
    Rien ne t'empêche d'utiliser plusieurs conteneur à différents endroit. Pour les jeux, je te conseil de regarder l'approche MVC (Model-View-Controler).
    Il n'est pas rare que tes implémentation intègrent plusieurs interfaces, aussi, la view pourra avoir un std::vector de ce qui l'intersse, et le controler une std::map d'une autre interface... Mais dont les implémentations se trouverons être le même objet.

    J'espère mettre fait compris, je vais essayer un """"asci-art"""" uml :

    view<>------Inte1*****Inte2------<>controler
    ***********^== Imple ==^*************

    Compréhensible ?
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Lavock Voir le message
    C'est là le problème quand on commence : souvent on s'aperçoit des erreurs de conception lors de la programmation. Il est vrai qu'on ne devrait pas revenir sur une bonne conception, mais il est quand même ardue qu'elle soit bonne au première essaie >< !
    Je ne demande pas qu'elle soit bonne au premier essai, je demande qu'il y en ait une avant d'écrire la première ligne de code... C'est différent

    Tout à la joie d'apprendre "un langage de programmation", les débutants se jettent trop souvent sur leur clavier et commence à "vomir des lignes et des lignes de code" sans avoir la moindre idée de la logique à mettre en oeuvre, des données à manipuler, des types de collections à utiliser, des services à attendre des différentes classes ou de la manières dont celles-ci seront organisées.

    Le polymorphisme, l'OO ou, simplement, la mise au point d'algorithme, sont des concepts qui s'apprennent de manière théorique, sans se rapporter au moindre langage.

    Il est primordial d'avoir cette "vue d'ensemble" que permet la conception avant de se lancer dans l'écriture du code, même si la conception n'est pas forcément parfaite du premier coup (après tout, même les plus expérimentés ne peuvent garantir que la conception sera idéale du premier coups) ou même s'il est nécessaire de revenir dessus parce que la mise en oeuvre met un manque en évidence.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #12
    screetch
    Invité(e)
    Par défaut
    Citation Envoyé par poukill Voir le message
    3 - Non c'est faux, voir dans la FAQ : http://cpp.developpez.com/faq/cpp/in...ssion_elements
    Citation Envoyé par La faq
    A noter que cette méthode ne fonctionne pas avec les conteneurs associatifs (set, map, multiset, multimap) : leur fonction erase ne renvoie rien.
    la méthode présentée plus haut fonctionne, mais elle est peu lisible. Une ligne de plus ne te tuera pas...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Libérer des pointeurs dans une std::map
    Par GaldorSP dans le forum SL & STL
    Réponses: 2
    Dernier message: 09/07/2005, 14h42
  2. Outils pour rechercher des fuites de memoires dans un prog
    Par elekis dans le forum Applications et environnements graphiques
    Réponses: 5
    Dernier message: 29/04/2005, 21h06
  3. fuite de memoire dans une liste de pointeur sur composant
    Par Nicolos_A dans le forum Composants VCL
    Réponses: 2
    Dernier message: 16/12/2004, 08h46
  4. Trier un std::map selon les valeurs plutot que les clés
    Par dj.motte dans le forum SL & STL
    Réponses: 2
    Dernier message: 13/11/2004, 21h54
  5. correction de fuite de memoire
    Par vince3320 dans le forum C
    Réponses: 38
    Dernier message: 28/06/2004, 11h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo