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 :

Je comprends pas l'utilté des constructeurs et destructeurs


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    octobre 2006
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2006
    Messages : 36
    Points : 17
    Points
    17
    Par défaut Je comprends pas l'utilté des constructeurs et destructeurs
    Salut tous le monde quelqu'un pourrait t'il m'expliquait l'utilité des constructeurs et destructeurs
    merci pour vos reponses

  2. #2
    Membre éprouvé

    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mars 2005
    Messages : 634
    Points : 1 205
    Points
    1 205
    Par défaut
    C'est vraiment la base de la programmation. Il y a nombre d'explications sur internet ou dans des bouquins, pas de raison de faire une explication spéciale, commence par regarder sur la page Cours C++. Et si tu veux une explication courte et simple, direction la FAQ -> http://c.developpez.com/faq/cpp/?page=constructeur et http://c.developpez.com/faq/cpp/?page=destructeur
    Fiquet
    - FAQ SDL
    - FAQ C++

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    octobre 2006
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2006
    Messages : 36
    Points : 17
    Points
    17
    Par défaut
    Y aussi ca que je comprend pas: qu'est ce qu'on appelle les objets en c++ ?

  4. #4
    Membre à l'essai
    Profil pro
    Développeur Java
    Inscrit en
    septembre 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : septembre 2006
    Messages : 11
    Points : 16
    Points
    16
    Par défaut
    T'inquiète dans 2 minutes quelqu'un va débarquer chez toi pour te donner un petit cours privé . . .
    As-tu au moins pris le temps de lire et de te renseigner (plus que de lire une fois) à ces sujets? As-tu essayé de mettre en oeuvre ces concepts dans des petits programmes?

    Le concept d'objet n'est pas limité au c++!

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    août 2004
    Messages
    5 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    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 460
    Points : 16 192
    Points
    16 192
    Par défaut
    J'ai l'impression qu'il te manque vraiment les concepts de base de la POO, qui sont certainement les plus difficile à définir à la va-vite, dans le cadre d'un post comme on peut en faire ici. Surtout qu'on ne sait pas sur quels concepts connus de toi on peut s'appuyer.

    En C++, quand tu définis :
    tu fais plusieurs choses. Tu déclare un objet en mémoire. Son type est entier, et il sera accessible par la variable i. Du plus, tu l'initialises avec la valeur 5.

    Certains restreignent le mot objet au cas où le type de la variable n'est pas un type de base du C++, mais un type crée par l'utilisateur, mais à la base, un objet n'est rien d'autre que ça. Et le constructeur est ce qui permet lors de la création d'initialiser correctement cet objet (comme dans l'exemple le fait qu'on puisse initialiser l'entier à 5).
    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.

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Le mot objet en C et en C++ a un sens particulier qui n'est pas nécessairement celui de la POO.
    Boost ftw

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    octobre 2006
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2006
    Messages : 36
    Points : 17
    Points
    17
    Par défaut
    Si par exmple j'ai ca qu'est ce que je peux inistialiser:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class nombre
    {
           public : 
           nombre()
           int nb1;
           int nb2;
    };

  8. #8
    Membre éprouvé Avatar de Jérémy Lefevre
    Homme Profil pro
    Développeur Java
    Inscrit en
    juin 2004
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Luxembourg

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

    Informations forums :
    Inscription : juin 2004
    Messages : 897
    Points : 969
    Points
    969
    Par défaut
    Salut elmodeno,
    Encore une fois je te conseil de t'interressé a des tutoriaux sur la POO avant de te lancer dans un projet!
    http://www.developpez.com/c/megacours/book1.html

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class nombre
    {
           public : 
           nombre()
           int nb1;
           int nb2;
    };
    En ce qui concerne ce code du declare un objet apeler nombre et tu as un constructeur -> nombre()
    ensuite ton objet fait reference a deux entiers nb1 et nb2 que tu peux initialisé dans ton constructeur....
    bon courage .....
    Rien ne se perd, rien ne se crée, tout se transforme

    ------- -------

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    octobre 2006
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2006
    Messages : 36
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par Jérémy Lefevre
    Salut elmodeno,
    Encore une fois je te conseil de t'interressé a des tutoriaux sur la POO avant de te lancer dans un projet!
    http://www.developpez.com/c/megacours/book1.html



    En ce qui concerne ce code du declare un objet apeler nombre et tu as un constructeur -> nombre()
    ensuite ton objet fait reference a deux entiers nb1 et nb2 que tu peux initialisé dans ton constructeur....
    bon courage .....
    Mais je peux tres bien initialisé nb1 et nb2 sans constructeur en faisant simplement ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    nombre.nb1=10;
    nombre.nb2=20;

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    novembre 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : novembre 2006
    Messages : 194
    Points : 220
    Points
    220
    Par défaut
    je vais prendre un exemple d'une liste chainée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class noeud
    {
      public:
        int valeur;
        noeud *suivant;
     
        noeud () { suivant = NULL; };
        ~noeud () { if (suivant != NULL) delete suivant; };
    };
     
    noeud *tete;
    à la fin du programme, pour libérer la mémoire sans destructeur, tu dois parcourir toutes la liste chaine pour detruire suivant en commencant par le dernier.
    avec le destructeur, tu efface le premier et le destructeur s'occupe d'effacer le reste

  11. #11
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    mai 2005
    Messages
    3 495
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : mai 2005
    Messages : 3 495
    Points : 5 495
    Points
    5 495
    Par défaut
    Citation Envoyé par elmodeno
    Mais je peux tres bien initialisé nb1 et nb2 sans constructeur en faisant simplement ca :
    nombre.nb1=10;
    nombre.nb2=20;
    C'est un problème d'encapsulation des données. Lors de la conception de ta nombre, tu représentes les données dont tu as besoin à l'aide de deux membres de type int. Il s'agit la d'un choix d'implantation que tu as fais lors de la conception de ta classe nombre.

    Maintenant, il se peut très bien que tu décides un jour de remplacer pour une raison x ou y les variables nb1 et nb2 par un tableau:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class nombre {
     
        public:
            int nb[2];
    }
    Si le code client qui utilise la classe nombre et s'appuye sur une initialisation explicite par accès direct à nb1 et nb2:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main()
    {
        nombre n;
        n.nb1 = 5;
        n.nb2 = 10;
     
        retour 0;
    }
    il y aura un problème au moment ou tu décides de changer certains détails d'implémentation (par exemple, utilisation d'un tableau au lieu de 2 entiers).
    Dans ce contexte, l'utilisation d'un constructeur permet d'assurer une initialisation propre de l'objet de type nombre sans créer de dépendance entre le code client et la structure interne de la classe. Exemple:
    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
    /* Exemple 1: implantation de nombre avec 2 entiers */
    class nombre {
        private:
            int nb1;
            int nb2;
        public:
            nombre(int n1, int n2)
            {
                 nb1 = n1;
                 nb2 = n2;
            }
     
            int getNombre1(void) const
            { return nb1; }
            int getNombre2(void) const
            { return nb2; }
    }
    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
    /* Exemple 2: implantation de nombre avec un tableau de 2 entiers */
    class nombre {
        private:
            int nb[2];
        public:
            nombre(int n1, int n2)
            {
                 nb[0] = n1;
                 nb[1] = n2;
            }
     
            int getNombre1(void) const 
            { return nb[0]; }
            int getNombre2(void) const 
            { return nb[1]; } 
    }
    Ton code client ne pourra maintenant plus accéder aux membres nb1, nb2 ou au tableau nb (qui sont déclarés private). L'initialisation doit obligatoirement passer par le constructeur, et les méthodes getNombre1 et getNombre2 permettent au client d'obenir les deux valeurs représentées par la classe nombre. Le même code client peut être utilisé quelque soit l'implantation de la classe client:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <iostream>
    #include "nombre.h"
     
    int main()
    {
        nombre n(5,10);
        std::cout << n.getNombre1() << ", " << n.getNombre2() << std::endl;
     
        return 0;
    }
    Le constructeur, ainsi que les méthodes getNombre1 et getNombre2 représente ce qu'on appelle l'interface de ta classe. Si le code client communique avec un objet de type nombre uniquement via cette interface (on peut le forcer à cela en déclarer private les membres donnée de la classe), il est possible au concepteur de la classe nombre d'en modifier l'implantation sans affecter le fonctionnement du code client. Le bénéfice en matière de maintenance et de réutilisation de code n'est pas directement visible sur un code aussi simple, mais le gain est énorme sur un projet grandeur nature.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  12. #12
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Tu veux sûrement dire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class noeud
    {
      public:
        int valeur;
        noeud *suivant;
     
        noeud () : suivant(NULL) { }
        ~noeud () { delete suivant; }
    };
    Ce qui de toutes manières est mauvais à mon avis.
    Quand tu détruis un noeud tu n'as pas à détruire l'ensemble de la liste.
    Boost ftw

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : octobre 2004
    Messages : 11 511
    Points : 29 908
    Points
    29 908
    Par défaut essaie déjà de comprendre l'idée de l'orienté objet...
    Salut,

    Tu devrais vraiment commencer par t'intéresser aux différents concepts qui régissent la programmation orientée objet...

    En effet, outre les constructeurs et les destructeurs, il y a un concept qui te fait vraiment défaut, c'est celui de la visibilité ou de "l'encapsulation" des données...

    L'idée, c'est que tout le monde ne doit pas pouvoir chipoter à tout ce qui fait ton objet...

    Ainsi, dans la vie de tous les jours...

    Quelque soit la chose que tu puisse prendre en main, tu ne pourras pas faire n'importe quoi...

    Tu pourras faire certaines actions dessus, tu pourras apréhender certaines caractéristiques, tu pourras, éventuellement, au moyens de certaines actions influencer sur certaines caractéristiques, tu pourras te rendre compte que certaines autres choses ont des caractéristiques identiques, mais tu ne verra pas *forcément* tout ce qui construit cette chose...

    Si on prend une tasse, par exemple:
    • Tu peux effectuer des action simples:
      • la remplir
      • la vider/boire son contenu
      • la laver
      • ...
    • Tu peux apréhender certaines de ses caractéristiques sans pouvoir les changer
      • sa forme
      • sa couleur
      • sa matière
      • sa capacité
      • ...

      Certaines de ces caractéristiques sont d'ailleurs partagées avec d'autres choses (avec un verre, ou une cannette de soda, par exemple)
    • Enfin, il y a certaines choses que, bien qu'elles fassent partie intégrante de la tasse, tu ne peux pas voir de l'extérieur:
      • la composition réelle de la matière
      • le coéfiscient de dissipation de la chaleur
      • la conductivité électrique
      • la dureté du matériaux
      • tout ce qui fait que la tasse est tasse et non canette de soda
      • ...

    Hé bien, en programmation orientée objet, l'idée est exactement la meme: tu vas fournir "quelque chose" à l'utilisateur, mais tu vas veiller à ce qu'il ne fasse pas n'importe quoi n'importe comment avec ce que tu lui fournis...

    Tu lui présentera un objet sur lequel il pourra agir au moyen d'actions déclarées en publique (qui modifieront éventuellement des éléments qui sont cachés de l'utilisateur), qui peut partager certaines informations ou actions déclarées en protégé avec d'autres choses du meme genre, mais qui garderont surement quelques "secrets", déclarés en privé, nécessaires pour "donner sa forme" à l'objet, mais que l'utilisateur n'a besoin ni de voir/connaitre, ni de pouvoir les modifier...

    Dans l'exemple que tu donnes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class nombre
    {
           public : 
           nombre()
           int nb1;
           int nb2;
    };
    il y a de fortes chances pour que tu ne veuilles pas que l'on puisse changer les valeurs de nb1 et nb2 n'importe comment...

    Tu vas donc décider de les mettre en protected si tu prévois qu'une classe dérivée doit pouvoir les modifier, en private si tu prévois que seule la classe nombre doit pouvoir y accéder/les modifier...

    Seulement, voilà... La question qui reste à se poser, c'est "A quoi va servir ta classe "

    Je vais, pour te faire comprendre la modifier un peu:
    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
     
    class coord3D
    {
        public:
            coord3D():X(5.0f),Y(10.0f),Z(15.0f){}
            coord3D(float x, float y, float z):X(x),Y(y),Z(z){}
            ~coord3D(){}
            const float* GetAsTab() const
            {
                int tab[3]={X,Y,Z};
                return tab;
            }
            const float GetX() const {return X;}
            const float GetY() const {return Y;}
            const float GetZ() const {return Z;}
            const float GetNormal() const
           {
                float retour=(x*x/2)+(y*y/2)+(z*z/2);
                return retour;
           }
        private:
           float X;
           float Y;
           float Z;
    };
    Ta classe qui contient trois réels ne se contente plus d'etre simplement une structure de trois réels...

    C'est devenu une coordonnée trois dimentions, dont l'utilisateur n'a meme pas besoin de savoir comment elle est construite...

    Tout ce qu'il sait, c'est qu'il peut récupérer au choix un tableau des trois dimentions, la valeur de chaque dimention prise séparément, ainsi que la valeur de la normale pour la position indiquée...

    Il n'a pas besoin de savoir comment ca fonctionne à l'intérieur, et il n'a aucune raison, une fois qu'il a disposé son point dans un univers à trois dimentions, d'aller le modifier...

    Et c'est là que tout l'intéret des constructeurs/destructeurs/foncteurs/accesseurs entre en jeu...
    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

    Profil pro
    Développeur informatique
    Inscrit en
    novembre 2006
    Messages
    7 583
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : novembre 2006
    Messages : 7 583
    Points : 17 840
    Points
    17 840
    Par défaut
    Citation Envoyé par koala01
    Salut,

    Tu devrais vraiment commencer par t'intéresser aux différents concepts qui régissent la programmation orientée objet...
    Justement c'est ce que l'initiateur de ce sujet cherche , une explication sur les constructeurs et destructeurs...pas qu'on lui tire dessus...
    n'oublie pas que toi aussi tu as été débutant

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : octobre 2004
    Messages : 11 511
    Points : 29 908
    Points
    29 908
    Par défaut
    Citation Envoyé par Mat.M
    Justement c'est ce que l'initiateur de ce sujet cherche , une explication sur les constructeurs et destructeurs...pas qu'on lui tire dessus...
    n'oublie pas que toi aussi tu as été débutant
    Mais je ne lui ai pas tiré dessus (ou du moins, je n'avais pas l'intention de le faire)...

    La preuve, j'ai essayé de lui présenter les choses sous un angle "compréhensible"...

    En effet, constructeurs et destructeurs (ainsi que tous les *teurs, d'ailleurs) ne prennent un sens qu'à partir du moment où l'on a compris l'intéret de ne pas mettre tout en visibilité "public"

    L'astuce, c'est que pour comprendre l'intéret de ne pas tout mettre en public, il faut avoir une idée de ce que permettent les autres solutions, et de pourquoi préférer mettre quelque chose en protected ou en private...
    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

  16. #16
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    27 233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

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

    Informations forums :
    Inscription : septembre 2005
    Messages : 27 233
    Points : 40 968
    Points
    40 968
    Par défaut
    Citation Envoyé par koala01
    En effet, constructeurs et destructeurs (ainsi que tous les *teurs, d'ailleurs) ne prennent un sens qu'à partir du moment où l'on a compris l'intéret de ne pas mettre tout en visibilité "public"
    Là, je ne suis pas d'accord.
    La RAII n'a pas grand-chose à voir avec la visibilité, par exemple...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  17. #17
    Expert éminent sénior

    Profil pro
    Développeur informatique
    Inscrit en
    novembre 2006
    Messages
    7 583
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : novembre 2006
    Messages : 7 583
    Points : 17 840
    Points
    17 840
    Par défaut
    Citation Envoyé par koala01
    Mais je ne lui ai pas tiré dessus (ou du moins, je n'avais pas l'intention de le faire)...
    Ok y'a pas de mal

  18. #18
    Membre à l'essai
    Profil pro
    Inscrit en
    octobre 2006
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2006
    Messages : 36
    Points : 17
    Points
    17
    Par défaut
    Merci de vos reponses mais ce que je comprend pas c'est que quel rapport y a entre l'encapsulation et les constructeurs et svp essayez de m'expliquer les constructeurs le plus facilement possible sans utiliser de termes tres difficile

  19. #19
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    mai 2005
    Messages
    3 495
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : mai 2005
    Messages : 3 495
    Points : 5 495
    Points
    5 495
    Par défaut
    Soit la classe suivante qui représente un Point:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Point {
        public:
            int x;
            int y;
    }
    Dans ton code client (par exemple la fonction main), tu décides de créer (on dit généralement instancier) et initialiser un objet de type Point. Tu procèdes donc de la manière suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main()
    {
        Point p;
        p.x = 5;
        p.y = 10;
     
        return 0;
    }
    Mettons que je décide d'écrire la classe Point différemment:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Point {
        int xy[2];
    }
    J'ai maintenant décidé de représenter l'abscisse et l'ordonnée de ton point à l'aide d'un tableau. Seulement voilà, ton code client, situé dans le corps de la fonction main, ne fonctionne plus, à cause du fait que tu as appelé explicitement les membres x et y pour initier ton objet.

    A quoi sert le constructeur et qu'est-ce que l'encapsulation des données?

    Comme tu l'as vu dans le code ci-dessus, une modification de la structure interne de ma classe Point a entraîné un disfonctionnement de ton code client.
    En plus de forcer l'initialisation d'un objet lors de sa création, l'utilisation d'un constructeur permet de cacher au client les détails d'implantation. En effet, en tant qu'utilisateur de la classe Point, tu n'as que faire de savoir que l'abscisse est représenté avec un membre appelé x, et que l'ordonnée est représentée par un membre y, ou que x et y sont représentés ensemble dans un tableau. Ce que tu veux représenter, c'est un point de coordonnées (5, 10), et c'est tout!.

    Le constructeur va te permettre ici de cacher à l'utilisateur de la classe les détails d'implantation. Je peux donc écrire ma classe Point de deux manière:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /*Variante 1: les coordonnées sont représentées par deux variables x et y*/
    class Point {
        int x;
        int y;
        public:
        Point (int abs, int ord) { x=abs; y=ord; }
    };
     
    /*Variante 2: les coordonnées sont représentées dans un tableau xy*/
    class Point {
        int xy[2];
        public:
        Point (int abs, int ord) { xy[0]=abs; xy[1]=ord; }
    };
    De cette manière, quelle que soit la variante utilisée pour implanter ma classe Point, toi, en tant qu'utilisateur désireux de créer un objet de type Point, tu n'as pas besoin de savoir si j'ai utiliser deux entiers ou un tableau pour représenter ton point de coordonnées (5, 10).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main()
    {
        Point p(5, 10); // réalise la création de l'objet et l'initialisation
        return 0;
    }
    Le constructeur m'assure, moi, le développeur de la classe Point, que ton code client fonctionnera toujours, quelque soit l'implantation que j'ai choisi pour représenter les données de la classe Point. Toi, en tant qu'utilisateur, tu n'as pas besoin de connaître les détails d'implantation de ma classe Point. Il te suffit de connaître l'interface proposée par le constructeur. Tu veux représenter un point de coordonnée (5, 10) et rien de plus, et le prototype du constructeur te renseigne sur la manière d'y parvenir.

    L'utilisation du constructeur t'assure que l'initialisation de l'objet est effectué dès sa création, et ceci sans que tu doive te documenter sur la structure des données internes de ton objet.

    A quoi sert le destructeur?
    Moi, le développeur de la classe Point, après une immense recherche bibliographique, j'ai découvert qu'il était préférable d'utiliser l'allocation dynamique lors de la représentation interne de mon point. J'écris donc une nouvelle implantation de ma fameuse et désormais célèbre classe Point
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Point {
        int *xy;
        public:
        // Constructeur de Point: on alloue maintenant dynamiquement la mémoire pour le tableau xy
        Point(int abs, int ord)
        {
            xy = new int[2];
            xy[0] = abs;
            xy[1] = ord;
        }
        // Destructeur: on a alloué de l'espace dynamiquement, il faut donc le libérer
        ~Point() { delete[] xy; }
    }
    Comme des millions d'utilisateurs utilisent désormais ma classe, je veux que les utilisateurs comme toi qui utilise Point comme dans le code ci-dessous puissent bénéficier des importantes améliorations et optimisations que j'ai apporté au code, sans modifier une seule ligne du code client qu'ils ont écrit. Ainsi, ton code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main()
    {
        Point p(5, 10);
        return 0;
    }
    doit fonctionner indépendamment des changement que j'ai apporté au code de Point. Pour toi, rien n'a changé et c'est bien le dernier de tes soucis de savoir que ton objet a alloué dynamiquementde la mémoire. Toutefois, il faut bien que la mémoire allouée soit libérée lors de la destruction de l'objet. Ce n'est pas toi qui va faire appel à l'opérateur delete[], car tu ne connais rien de l'implantation de ma classe Point. Il faut donc que l'espace alloué soit libéré automatiquement à la destruction de l'objet. C'est à cela que sert le destructeur de la classe, à libérer des resources proprement et automatiquement à la destruction d'un objet (je simplifie un peu, là).


    Voilà, j'espère avoir contribué un peu à clarifier certaines choses. Meilleures salutations

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

Discussions similaires

  1. [pygame] Je ne comprends pas la mécanique des Mask
    Par Luke spywoker dans le forum Programmation multimédia/Jeux
    Réponses: 5
    Dernier message: 17/07/2012, 00h59
  2. [WS 2003] [TSE] Ne comprends pas la Gestion des licence
    Par alex_m94 dans le forum Windows Serveur
    Réponses: 7
    Dernier message: 13/10/2009, 18h57
  3. Réponses: 6
    Dernier message: 12/08/2007, 14h29
  4. [MySQL] Php, je ne comprends pas comment faire pour introduire des données dans une table
    Par Liondd dans le forum PHP & Base de données
    Réponses: 23
    Dernier message: 14/12/2006, 13h53
  5. sql ne comprend pas mon where!et me demande des parametres
    Par marie10 dans le forum Langage SQL
    Réponses: 10
    Dernier message: 20/04/2004, 12h08

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