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 :

Effacer des structures


Sujet :

C++

  1. #1
    Membre averti

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 177
    Points : 321
    Points
    321
    Par défaut Effacer des structures
    Bonjour! Voilà j'ai un petit problème concernant la gestion de la mémoire lors de l'effacement. Mon but était de créer des structures et en définir une principale qui regroupe le tout de façon dynamique.

    Ma première structure était:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    typedef struct Dimension
    {
             int x;
             int y;
             int Width;
             int Height;
             int bits;
    } *Dimension_Screen;
    La seconde était:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct Information
    {
             string Title;
             string icon;
    } *Information_Window;
    Et la dernière qui regroupe le tout:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct Device
    {
             Dimension_Screen dim;
             Information_Window iw;
             bool fullscreen;
    } *GUI_Device;
    Voilà les trois structures. Bien sûr je me sert que de la troisième pour ma classe.

    la classe ressemble à ça pour l'initialisation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class GUI
    {
    public:
             GUI(GUI_Device device);
             ~GUI(void);
    private:
             GUIDevice device;
    A l'initialisation de la classe GUI:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    GUI::GUI(GUI_Device device)
    {
             this->device = NULL;
             this->device = new GUIDevice;
             this->device = device;
    }
    Et le destructeur ou il y a le problème que je connais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    GUI::~GUI(void)
    {
             if(this->device != NULL)
                      delete[] this->device;
    }
    Je sais que c'est la que ça plante, à cause des autres structures dynamiques. Si quelqu'un connaissait un moyen de supprimer les structures à l'intérieur pour éviter d'avoir erreur de segmentation, je l'en remercie d'avance.

    J'avais aussi essayé ça, mais ça ne marche pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    GUI::~GUI(void)
    {
              if(this->device != NULL)
             {
                      delete[] this->device->Dimension_Screen;
                      delete[] this->device->Information_Window;
                      delete[] this->device;
             }
    }


  2. #2
    Invité
    Invité(e)
    Par défaut
    Déjà, si tu alloues avec
    device = new GUIDevice;
    tu dois désallouer avec
    delete device;
    delete[] c'est pour les tableaux.

    Ensuite, si, comme dans ton second exemple tu désalloues les structures Dimension_Screen et Information_Window alors que tu ne les as pas allouées, ca ne peut pas bien se passer.

    Enfin, si tu as des structures qui contiennent des pointeurs que tu alloues et désalloues dans les constructeurs et les destructeurs, il te faut définir un opérateur et un constructeur de copie. Sinon, dès que tu vas copier des instances ou initialiser une instance à partir d'une autre, il va se passer des choses terribles...


    Grosso modo, ta classe doit ressembler à

    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
     
    struct MaClasse {
        Membre *leMembre;
     
        // constructeur
        MaClasse() {
            leMembre=new Membre;
       }
       // constructeur de copie
       MaClasse(const MaClasse &p) {
           leMembre=new Membre;
           *leMembre=p->leMembre; 
    // si c'est une structure, il va te falloir une fonction de copie, là
       }
       // destructeur 
       ~MaClasse() {
           delete leMembre;
       }
       // operateur de copie
       MaClasse &operator=(const MaClasse &p) {
          if(this!=&p) *leMembre=p->leMembre;
          return *this;
       }
    };
    Si tu as des classes emboitées, contenant des pointeurs sur d'autres classes, etc... il va te falloir un code similaire à chaque niveau...

    Cependant, dans l'exemple que tu cites, il vaudrait peut être mieux utiliser directement les classes : Dimension, Information et Device. Elles seraient directement allouées, et correctement copiées, à l'instanciation de tes classes, sans constructeur, destructeur ou opérateur de copie...

    Francois
    Dernière modification par Invité ; 01/05/2009 à 01h49.

  3. #3
    Membre averti

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 177
    Points : 321
    Points
    321
    Par défaut
    Merci pour ta réponse! Je vais modifier de suite.

    Mais si je met des classes à la place des struct. Comment je fais pour que ma classe GUI qui mettait une struct Device en argument, la récupérer sous la forme d'une classe initialisé dans le Main?

    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
     
     
    int main(int argc, char** argv)
    {
            Device* device = new Device();
            device->position(10, 10, 800, 600, 32);
            device->...;
     
            GUI* gui = new GUI(device);      // Récupération des information du device
            gui->show();                          // Affectation du device
     
            ...
            ...
     
            return EXIT_SUCCESS;
    }
    Voici le nouveau device sous la forme de classe:

    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
     
    class Device
    {
    public:
        Device(string Title, string Icon);
        virtual ~Device(void);
     
        void Dimension(int x, int y, int Width, int Height, int bits);
        void Style(GUIOptions options);
     
    protected:
        Dimension_Screen dim;
        int X;
        int Y;
        int Width;
        int Height;
        string Title, Icon;
    };
    et ainsi que le GUI:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class GUI : public Device
    {    
    public:
        GUI(Device device);
        virtual ~GUI(void);
     
        void Show(void);
     
    private:
    };
    Je précise que ça fait longtemps que je n'ai plus fait de C++ et que j'ai un peu oublié l'essentiel .


  4. #4
    Invité
    Invité(e)
    Par défaut
    Pas de souci...

    Les classes et les structs, en fait, c'est un peu la même chose... La seule différence (à ma connaissance, peut qu'être qu'un spécialiste pourra nous en dire plus), c'est que dans une classe, les membres sont privés par défaut, alors que dans une struct ils sont publics.

    Ce qui est en cause, ici, c'est de savoir si les membres de tes classes agrégées (par exemple GUI) doivent être des instances de tes classes/structures, ou des pointeurs vers ces instances.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class MaClasse {
      MonTypeMembre membre;
    }
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class MaClasse {
      MonTypeMembre *ptr_vers_membre;
    }
    Dans le premier cas, le constructeur de MonTypeMembre est appelé quand une instance de MaClasse est construite, c'est fait automatiquement, pareil pour le destructeur. C'est simple. Dans cette situation, le mieux est d'affecter des valeurs aux composants de membre dans le constructeur de MaClasse (en fait, tu mets tout dans MaClasse... MonTypeMembre devenant, essentiellement, un raccourci d'écriture).

    Dans le second cas, tu as un pointeur comme membre de ta classe, il va donc te falloir allouer (dans le constructeur ou ailleurs), ce vers quoi il pointe.

    Pour l'initialisation tu te retrouves avec

    mongui=new GUI;
    mongui.membre=new MonTypeMembre;

    L'avantage est que tu peux ainsi mieux contrôler ce que tu fais (par exemple partager une même instance du membre sur plusieurs instances de ta classe, ou l'allouer à un autre moment que dans le constructeur). L'ennui, c'est qu'il faut gérer toi même l'allocation, la destruction, et tous les trucs mignons qui peuvent se produire quand tu copies des données.

    class GUI : public Device

    c'est encore autre chose... Cette fois, tu dérives GUI de Device : au lieu de "contenir un Device", un GUI est maintenant une "sorte de Device". Dans ce cas, du n'as pas besoin de passer un Device au constructeur, tu fais juste

    mongui=new GUI;

    et là tu peux initialiser ses membres Title, Icon et les autres
    mongui.Title= ..., mongui.Icon=..., etc...

    Francois

  5. #5
    Membre averti

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 177
    Points : 321
    Points
    321
    Par défaut
    C'est bon c'est résolu, je vais le faire par héritage de classe. J'ai testé est ça fonctionne à merveille.

    Ce que tu m'as montrées c'est très bien, mais je ne jamais maitrisé et que je ne connaissait pas le constructeur de recopie. Pour l'instant je garde l'héritage et je vais faire des recherche sur ces constructeurs de copie. Merci pour ton aide.

    Pour information, "MonTypeMembre" est-ce une classe ou une structure?


  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par terminator59140 Voir le message
    Pour information, "MonTypeMembre" est-ce une classe ou une structure?
    C'est comme tu veux... En C++, à l'exception du fait que les membres d'une class sont privés par défaut et que ceux d'une struct sont publics par défaut, class et struct sont complètement identiques.

    Tu peux par exemple avoir dans une struct des membres privés ou protégés, des constructeurs, des destructeurs, des fonctions virtuelles, tu peux même hériter d'une struct. Et, en utilisant le mot "private", tu peux rendre inaccessible les données d'une struct.

    C'est pareil, quoi...

    En pratique, on définit souvent comme struct des types utilisateurs qui sont en fait des "agrégats de données" que l'on écrit et consulte, avec peu de fonctions membres, et comme class des types qui se définissent davantage par leurs fonctions membres (et qui tendent à cacher leurs données).

    Aussi, les programmeurs qui viennent du C utilisent souvent des structs (celles du C++ sont bien plus complètes que celles du C), ceux qui sont tombés dans la marmite objet quand ils étaient petits, et frémissent à l'idée qu'une variable puisse être publique, ne font guère que des classes.

    Mais bon, c'est purement psychologique.

    Personnellement, j'écris beaucoup de struct, mais je recommande de plus en plus de tout mettre en class. Comme struct n'est pas très souvent employé, et comme les struct C étaient assez différentes des struct C++, un struct dans du code destabilise certains programmeurs... Et puis, si tu mets des structs dans un projet, tu dois être prêt à t'embarquer dans de longs débatns sur l'encapsulation, la POO et tous les risques que ce malheureux mot struct fait courir au projet, à l'équipe, à la société et au client... En ce sens, écrire class, ca gagne du temps...

    Francois

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

Discussions similaires

  1. [VB.Net] Comment effacer des traits sur un graphique ?
    Par bert24 dans le forum Windows Forms
    Réponses: 2
    Dernier message: 27/09/2005, 14h20
  2. (EXCEL) Effacer des images gif insérées sur une feuille ?
    Par romo3 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 27/08/2005, 21h31
  3. afficher/effacer des <tr> sous Firefox
    Par Macintoc dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/06/2005, 10h10
  4. Effacer des doublons
    Par ben53 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 12/07/2004, 17h56
  5. Comment effacer des Items d'un TListView ?
    Par boyerf dans le forum Composants VCL
    Réponses: 4
    Dernier message: 11/11/2002, 10h19

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