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 :

Tableau Dynamique procédure de copie


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2009
    Messages : 10
    Points : 9
    Points
    9
    Par défaut Tableau Dynamique procédure de copie
    Bonjour à tous ,

    J'ai crée une classe Personne avec ses caractéristiques que je dois mettre en File sans pour autant utiliser la classe Vector ou toute classe héritée ni même Queue .

    La seule solution ( à mon niveau ) est de créer un tableau dynamique. J'ai lu dans la FAQ du forum:
    Pour agrandir une zone (généralement un tableau) allouée via l'opérateur new il faudra faire la manipulation à la main :
    - Allouer un nouvel espace mémoire de la taille souhaitée
    - Y copier son contenu
    - Libérer l'ancien espace mémoire
    J'ai donc fait une nouvelle classe File dans laquelle j'ai un attribut de la forme :

    Personne *Tab;

    Rien ne me parait compliqué jusqu'au moment d'ajouter une personne dans la file c'est assez affreux, j'en arrive même à faire "bipper" mon pc lors de certaines éxécution du code source.

    Je me pose des questions :
    Comment bien utiliser le constructeur par copie? ( je n'ai pas de problème pour le créer, c'est plutot pour m'en servir)
    va-t-il toujours en paire avec operator= ?

    si vous avez quelques exemples je suis preneur.

  2. #2
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Bonjour.

    Tu arrive à faire biper le pc O_o... je me demande bien comment tu fais...

    enfin bon, de manière générale, on peut créer une classe liste comme suit:
    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
    class ListePersonne 
    {
       Personne* Tab;
       size_t Taille;
    public:
       ListePersonne():Taille(0){}
       void Ajouter(const Personne & P){
          if (Taille!=0)
          {
              //On recopie l'adresse de Tab.
              Personne* provTab=Tab;
              //On crée un nouveau Tab de taille Taille+1
              Tab=new Tab[++Taille];
              //On recopie l'ancien tableau dans le nouveau
              for(size_t i=0;i<Taille-1;++i)
                 Tab[i]=provTab[i];
              //et on supprime l'ancien !
              delete [] provTab;
           }
           else
              Tab=new Tab[++Taille];
           Tab[Taille-1]=P;
        }
       ~ListePersonne()//destructeur, il faut désallouer Tab
       {
           if (Taille!=0)
              delete [] Tab;
       }
    };
    voilà, tu a les fonctions sensibles. essaye de les comprendre et crée le reste.


    Bonne chance
    Méphistophélès
    Si la solution ne résout pas votre problème, changez le problème...
    Cours et tutoriels C++ - FAQ C++ - Forum C++.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 617
    Points : 30 639
    Points
    30 639
    Par défaut
    Salut, et bienvenue sur le forum.

    Pourrais tu expliquer à quelle restriction tu es confronté qui t'empêcherait de recourir aux collections standard du C++ ou à celle de boost

    En effet, l'idéal reste toujours de manipuler les collections d'objets propres au C++ tant que faire se peut et de n'envisager de passer à un tableau "C style" que lorsque tu n'a vraiment pas le choix (lorsqu'il s'agit d'appeler une fonction écrite en C, par exemple)...

    Avec la classe vector, par exemple, il "suffit", pour obtenir un tableau C style, de récupérer l'adresse de l'élément se trouvant à l'index 0...

    La norme garanti en effet que les différents éléments d'un std::vector sont placés de manière contigüe en mémoire.

    Ainsi, avec une fonction "C" dont la signature serait proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void foo(Personne* tab, size_t size);
    tu peux parfaitement envisager de travailler sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    std::vector<Personne> vecteur;
    /* insertion / ajout des éléments dans le vecteur */
    foo(&vecteur[0],vecteur.size());
    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

  4. #4
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2009
    Messages : 10
    Points : 9
    Points
    9
    Par défaut
    Merci pour ces deux réponses.

    Méphistopheles j'ai bien compris ta réponse je vais dès maintenant le mettre en pratique et d'ici ce soir je posterai pour d'éventuels nouveaux problèmes ou juste pour signaler que le sujet est résolu

    Je t'explique pour les restrictions koala01.
    Je suis étudiant, j'ai déjà fais en TP de C++ la version utilisant la classe vector c'est très facile à manipuler j'ai vraiment pas eu de difficulté.
    A la fin du cours l'enseignant nous a conseillé de refaire ce travail sans l'utiliser pour pratiquer pendant nos vacances et me voilà .

    Tu arrive à faire biper le pc O_o... je me demande bien comment tu fais...
    J'aurais aimé te montrer ce qui s'affichait en console mais je n'arrive pas à réécrire mon erreur. Quelque chose qui m'a surpris, c'est qu'a la fin d'un long discours incompréhensible ( pour moi ) dans la console, il y a eu plusieurs ligne vide suivi de 3 smileys, faudrait vraiment que je retrouve ça pour le poster^^.

  5. #5
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int x = 12;
     
     
    std::string myString;
     
    string += x;

    devrait reproduire ton jolie bug (bip + smyley). Par ailleurs je comprends pas trop cette approche (celle du prof) si tu réussis avec le vector alors tant mieux, pourquoi se mélanger les pinceaux avec ce genre de code C-like?
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 617
    Points : 30 639
    Points
    30 639
    Par défaut
    Citation Envoyé par Geo34 Voir le message
    <snip>
    Je suis étudiant, j'ai déjà fais en TP de C++ la version utilisant la classe vector c'est très facile à manipuler j'ai vraiment pas eu de difficulté.
    A la fin du cours l'enseignant nous a conseillé de refaire ce travail sans l'utiliser pour pratiquer pendant nos vacances et me voilà .
    Y a des coups de pied quelque part qui se perdent...

    Pas de ton coté, parce que tu ne fais que suivre les instructions du prof, mais du coté du prof, car c'est une très mauvaise idée que d'inciter les élèves à prendre des habitudes issues du C alors que le standard fournit tout ce qui permet de sécuriser son travail et de se faciliter la vie

    Si ton prof est ouvert à la discussion, tu peux lui dire de ma part qu'il mérite ce coup de pied
    J'aurais aimé te montrer ce qui s'affichait en console mais je n'arrive pas à réécrire mon erreur. Quelque chose qui m'a surpris, c'est qu'a la fin d'un long discours incompréhensible ( pour moi ) dans la console, il y a eu plusieurs ligne vide suivi de 3 smileys, faudrait vraiment que je retrouve ça pour le poster^^.
    Ca, c'est, typiquement, le signe que tu corromps la mémoire à un moment donné... ou que tu as un pointeur non initialisé quelque part...

    Au fait, le terme file représente une structure capable de représenter un système FIFO (First In, First Out), que l'on pourrait comparer à ce qui se passe dans les magasins lorsqu'il y a du monde aux caisses...

    Il n'y a, normalement, pas besoin de manipuler un pointeur de personne, mais il est intéressant de créer en réalité deux structures:
    • la première (nommons la "Element") qui représente un élément unique de la file, qui contient comme information la personne et... le moyen d'accéder à l'élément suivant
    • la deuxième (nommons la "File") qui représente... l'intégralité (tous les éléments) de la file

    Typiquement, cela 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
    class Element
    {
        private:
            Personne pers;
            Element *suivant;
    };
    class File
    {
        private:
            /* le premier élément de la file */
            Element * premier;
            /* il est souvent intéressant de connaitre aussi le dernier élément  */
            Element *dernier;
            /* et la taille */
            size_t taille;
    }
    Il faut penser que:
    l'insertion d'un élément dans la file va occasionner des changements:
    • au niveau du pointeur "suivant" du dernier élément de la file
    • des changement au niveau de la taille de la file
    • peut etre (si c'est le premier élément que l'on ajoute) au niveau du premier élément de la file
    et que la suppression (du premier élément, car c'est normalement le seul que l'on puisse supprimer du fait que c'est un FIFO), va occasionner des changement fortement similaires
    [EDIT]En outre, le pointeur suivant doit être initialisé systématiquement à la seule adresse connue pour être invalide mais qui soit testable: NULL, modifié uniquement lorsqu'il y a lieu et la validité de l'adresse doit être systématiquement testée avant de tenter d'accéder à l'élément suivant
    [/EDIT]
    PS: le test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if(tab)
        delete [] tab;
    est tout à fait inutile...

    delete et delete[] sont prévus pour ne rien faire s'ils s'appliquent sur NULL, et cela ne garanti de toutes manières rien si, par malheur, tab n'est pas NULL mais est invalide
    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 émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Y a des coups de pied quelque part qui se perdent...
    Pourquoi ?
    C'est très bien je trouve ce que fait le prof. Pendant le TP les élèves utilisent std::vector qui est clairement beaucoup plus efficace et plus sûr qu'une solution à la main, en revanche, pour les intéressés il conseille de refaire l'exercice sans std::vector pendant les vacances, histoire de mieux comprendre les entrailles de la bête (ce qui peut servir, parfois)

    Geo34, si tu comprends l'anglais je te conseille le livre Accelerated C++. Il y a justement un long chapitre assez génial qui reconstruit std::vector de A à Z de manière extrêmement pédagogique et qui m'avait vraiment ouvert les yeux à l'époque. Grâce à Accelerated C++, Geo34, toi aussi tu seras capable de lire les header de la STL directement sans sombrer dans la folie. (c'est même presque clair !)

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 617
    Points : 30 639
    Points
    30 639
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Pourquoi ?
    C'est très bien je trouve ce que fait le prof. Pendant le TP les élèves utilisent std::vector qui est clairement beaucoup plus efficace et plus sûr qu'une solution à la main, en revanche, pour les intéressés il conseille de refaire l'exercice sans std::vector pendant les vacances, histoire de mieux comprendre les entrailles de la bête (ce qui peut servir, parfois)
    <snip>
    Parce que, de mon avis, il est presque néfaste d'entretenir l'idée que C++ n'est qu'une "surcouche" de C, et qu'il y a moyen de s'en sortir en réinventant - souvent mal et au prix de problèmes sans noms - la roue en se basant sur les capacités du C...

    Que l'on étudie le C, et qu'on connaisse ses capacités (voire, qu'on le maitrise pour certains) est une chose louable, que l'on incite les élèves à entretenir la confusion en est une autre parce que ça ne fait justement ... que ça...

    Je me suis suffisamment étendu par le passé sur ce point de vue pour qu'il te soit presque aisé de retrouver mon argumentation complète

    Mais encore une fois, ce n'est qu'un avis personnel... Mais que je partage
    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

  9. #9
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    Tout à fait, mais peut-être que le but de ce prof en poussant ses élèves dans ces deux voies est de leur montrer, exemple à l'appui, combien il est plus simple et plus rapide d'utiliser std::vector

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 617
    Points : 30 639
    Points
    30 639
    Par défaut
    Sauf que cela me fait quelque peu penser au parent qui insiste pour que le gamin pose la main sur la taque électrique brulante pour lui apprendre que c'est chaud et qu'il ne faut donc pas le faire

    Comprenons nous, je trouve parfaitement cohérent d'essayer de faire de manière à ce que les étudiants comprennent "les entrailles de la bête"...

    je n'aurais donc rien contre le prof qui, après avoir appris à ses étudiants à utiliser les différents conteneurs et les avoir initiés aux "arcanes" des template et des traits de politique les incitent, à l'instar de Accelerated C++, à essayer de "recréer" une classe vector, quitte à ce qu'elle soit allégée, et quitte à ce que cela nécessite de recommencer à manipuler l'allocation dynamique en dehors des cas de polymorphisme et les memcpy et autres joyeusetés...

    Le problème, c'est que les cours de C++ ne vont que rarement moitié assez loin que pour permettre aux étudiants d'y arriver...(on a déjà souvent beaucoup de chance si les template sont abordés en cours )

    Par contre, de ce qui ressort des indications de Geo34 (mais peut être les ai-je mal interprété ), ici, le prof leur a appris l'utilisation des conteneurs (ce qui est déjà un bon point pour lui ), puis il vient leur dire
    maintenant, faites comme si ca n'existait pas, et amusez vous à coup d'allocation dynamique, un peu comme ce qui se fait en C...
    Et ca, j'estime que ca n'a aucun intérêt
    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

  11. #11
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2009
    Messages : 10
    Points : 9
    Points
    9
    Par défaut
    Bonsoir,

    En ce qui concerne mon projet, j'en suis venu à bout sans problème grâce à vos explications et bien heureusement je n'ai plus aucun bruit lors de l'exécution .
    Le sujet est donc "Résolu".

    Je pense qu'en effet il n'est pas utile de faire faire ce genre de démarche aux étudiants, des moyens nouveaux sont mis en place pour nous faire éviter tout ces efforts, il faut les utiliser. Si l'étudiant souhaite approfondir ses connaissances très bien mais il serait plus intéressant de "passer" sur ses exercices dans le programme pour intégrer de nouvelles notions.
    Comme vous pouvez le voir il ne reste qu'un mois et demi de cours ( grand maximum ) et nous avons tout juste appris à gérer des conteneurs, intégrer les pointeurs et se servir de quelques classes propre au C++, n'importe quel amateur en programmation peut acquérir ces connaissances en mois d'un mois ( je suis large ) en travaillant de lui même .
    Je ne vais pas me plaindre de la facilité du programme évidemment mais je préfèrerai en apprendre un peu plus .

    Je vous remercie pour toute vos réponses, je découvre le forum avec grand plaisir.

  12. #12
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Citation Envoyé par koala01 Voir le message
    PS: le test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if(tab)
        delete [] tab;
    est tout à fait inutile...

    delete et delete[] sont prévus pour ne rien faire s'ils s'appliquent sur NULL, et cela ne garanti de toutes manières rien si, par malheur, tab n'est pas NULL mais est invalide
    Heu... ou est-ce que tu vois ça ? personellement, je fait un test sur la taille du tableau et non sur tab, justement pour éviter le problème lié au pointeur invalide... qui il me semble n'est lui pas garanti par la norme...
    Méphistophélès
    Si la solution ne résout pas votre problème, changez le problème...
    Cours et tutoriels C++ - FAQ C++ - Forum C++.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 617
    Points : 30 639
    Points
    30 639
    Par défaut
    Citation Envoyé par méphistopheles Voir le message
    Heu... ou est-ce que tu vois ça ? personellement, je fait un test sur la taille du tableau et non sur tab, justement pour éviter le problème lié au pointeur invalide... qui il me semble n'est lui pas garanti par la norme...
    Ouppss... Au temps pour moi... j'avais vu le test sans le vérifier

    Si, si, la norme garanti que delete NULL est sans effet
    Citation Envoyé par la norme 5.5.35 §2
    If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section. In either alternative, if the value of the operand of delete is the null pointer the operation has no effect.
    <snip>
    [EDIT]Par contre, ce qui a un comportement indéfini, c'est l'invocation de delete sur un pointeur invalide ... Et ca, si tu invalide ton pointeur mais que tu ne remet pas la taille à 0 ET le pointeur à NULL, tu cours un risque identique
    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

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 617
    Points : 30 639
    Points
    30 639
    Par défaut
    En fait, le seul moyen d'avoir la certitude de ne pas commencer à faire une "soupe" avec l'allocation dynamique, c'est de prendre les habitudes:
    1. d'initialiser le pointeur à NULL à sa déclaration, en attente de l'allocation dynamique
    2. de réinitialiser le pointeur à NULL juste après le delete / delete[]

    Les deux seuls cas dans lesquels il n'est pas indispensable de remettre un pointeur pour lequel nous avons invoqué delete / delete[] sont:
    1. Lorsque la libération de la mémoire s'effectue dans le destructeur de l'objet
    2. Lorsqu'il s'agit d'un pointeur temporaire, propre à une fonction
    car, dans les deux cas, le pointeur devient inaccessible...

    Mais, cela n'empêche que, si l'instance de la structure (ou de la classe) qui est détruite a été gérée sous la forme d'un pointeur, il faille remettre ce pointeur à NULL
    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

  15. #15
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Geo34 Voir le message
    Si l'étudiant souhaite approfondir ses connaissances très bien mais il serait plus intéressant de "passer" sur ses exercices dans le programme pour intégrer de nouvelles notions.
    Disons qu'écrire une classe de ce genre, qui gère manuellement une ressource, permet de bien comprendre les notions essentielles en C++ de constructeur de copie, opérateur=, destructeur. Et une classe comme un vecteur fait partie des exemples simples de classe gérant une ressource.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  16. #16
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Si, si, la norme garanti que delete NULL est sans effet
    Je n'ai jamais dis le contraire :p
    Citation Envoyé par méphistopheles Voir le message
    je fait un test sur la taille du tableau et non sur tab, justement pour éviter le problème lié au pointeur invalide... qui il me semble n'est lui pas garanti par la norme...
    pour moi, invalide !=NULL...

    Citation Envoyé par koala01 Voir le message
    En fait, le seul moyen d'avoir la certitude de ne pas commencer à faire une "soupe" avec l'allocation dynamique, c'est de prendre les habitudes:
    1. d'initialiser le pointeur à NULL à sa déclaration, en attente de l'allocation dynamique
    2. de réinitialiser le pointeur à NULL juste après le delete / delete[]

    Les deux seuls cas dans lesquels il n'est pas indispensable de remettre un pointeur pour lequel nous avons invoqué delete / delete[] sont:
    1. Lorsque la libération de la mémoire s'effectue dans le destructeur de l'objet
    2. Lorsqu'il s'agit d'un pointeur temporaire, propre à une fonction
    car, dans les deux cas, le pointeur devient inaccessible...

    Mais, cela n'empêche que, si l'instance de la structure (ou de la classe) qui est détruite a été gérée sous la forme d'un pointeur, il faille remettre ce pointeur à NULL
    Je m'aperçois que je me suis souvent compliqué la vie pour rien.Bien que dans le cas en question dans ce topic, ce n'est pas nécessaire car tester une condition sur taille est équivalent à en tester une sur le pointeur, néanmoins, je dois (à ma grande honte) reconnaître que j'avais tendance à rajouter dans certaines classes un booléen pour gérer le problème, ayant banni le NULL qui était pour moi un C-like à bannir en C++... force est de constater que ça m'aurais bien simplifié la tâche si j'y avais pensé 10 minutes....

    merci pour ces conseils
    Méphistophélès
    Si la solution ne résout pas votre problème, changez le problème...
    Cours et tutoriels C++ - FAQ C++ - Forum C++.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 617
    Points : 30 639
    Points
    30 639
    Par défaut
    Citation Envoyé par méphistopheles Voir le message
    Je n'ai jamais dis le contraire :p
    Oui, je me suis rendu compte par la suite que j'avais lu trop vite, et mal interprété ce que tu disais... Au temps pour moi
    pour moi, invalide !=NULL...
    invalide signifie que l'adresse mémoire vers laquelle il pointe a été libérée...

    Le fait est que, si tu ne pense pas à remettre un pointeur à NULL lorsqu'il devient invalide, tu risque tout autant de ne pas penser à remettre une autre variable à 0 (une variable qui représenterait le nombre d'objets de ta collection, par exemple )

    Le seul moyen d'éviter toute tentative d'accès à un pointeur invalide (hormis, bien sur, le recours aux pointeurs intelligents) est donc de veiller à ce que la libération de la mémoire provoque bel et bien le passage de tous les pointeurs pointant sur cette adresse à NULL
    Je m'aperçois que je me suis souvent compliqué la vie pour rien.Bien que dans le cas en question dans ce topic, ce n'est pas nécessaire car tester une condition sur taille est équivalent à en tester une sur le pointeur,
    Exactement
    néanmoins, je dois (à ma grande honte) reconnaître que j'avais tendance à rajouter dans certaines classes un booléen pour gérer le problème
    Il n'y a pas de honte à le faire, mais il faut voir si c'est utile ...

    Un cas précis dans lequel il est même intéressant de travailler ainsi serait un singleton prenant une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Singleton
    {
        public:
            static Singleton& instance()
            {
                static Singleton obj;
                return obj;
            }
    };
    pour lequel tu voudrais traquer les référence mortes...

    Si, par exemple, tu veux un singleton pour la gestion du clavier, un deuxième pour la gestion de l'écran et un troisième pour la gestion d'un système de log, mais que tu souhaite que celui responsable du logging ne soit activé qu'en cas de besoin (donc, après ceux de gestion de l'affichage et du clavier), et que tu prévois, malgré tout la possibilité de logger une information lors de la destructeur de ces deux managers

    (exemple tiré de Modern C++)
    ayant banni le NULL qui était pour moi un C-like à bannir en C++...
    NULL est effectivement issu du C...

    Mais il n'a aucune alternative en C++ à l'heure actuelle...

    Tu n'a donc pas le choix de l'utiliser

    Lorsque C++0x sera implémenté partout, tu devrais disposer de nullptr (me semble-t-il), qui permettra de représenter clairement un pointeur... nul
    force est de constater que ça m'aurais bien simplifié la tâche si j'y avais pensé 10 minutes....

    merci pour ces conseils
    C'est à cela que sert un forum: il y a toujours plus dans deux têtes que dans une
    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

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 07/08/2008, 14h09
  2. Réponses: 4
    Dernier message: 01/01/2007, 10h26
  3. Copie de tableau dynamique Tridimensionel
    Par Zenol dans le forum C++
    Réponses: 23
    Dernier message: 19/12/2005, 16h00
  4. [Kylix] tableau dynamique
    Par sdoura2 dans le forum EDI
    Réponses: 1
    Dernier message: 31/10/2002, 08h57
  5. Réponses: 4
    Dernier message: 13/05/2002, 16h43

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