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 :

constructeur : renseigner paramètres


Sujet :

C++

  1. #1
    Invité
    Invité(e)
    Par défaut constructeur : renseigner paramètres
    Bonjour,

    J'aimerais savoir si quand on a l'implémentation d'un constructeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Constr::Constr(QObject *parent=0){}
    , est-ce qu'on est obligé de renseigner le paramètre lors de l'appel du constructeur ? Car celui-ci ne pointe vers rien...

  2. #2
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Non : le =0 dit que si le paramètre n'est pas précisé, 0 est sa valeur par défaut.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  3. #3
    Invité
    Invité(e)
    Par défaut
    ah ok.
    Quel intérêt, dans la pratique, lors de l'initialisation d'un objet, de lui passer en paramètre un pointeur vers un objet parent ?
    On m'a déjà dit que cela pouvait servir à détruire l'objet automatiquement si le parent était détruit.
    Tout cela est pour moi un peu abstrait : dans le cas où l'on créer une GUI, l'objet est automatiquement détruit à la fin du programme... ?

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Il existe un design pattern nommé "composite" qui permet, pour faire simple, de gérer une relation "contenant" à "contenu" sous une forme arborescente, et de gérer n'importe quel élément que l'on retrouve dans cette arborescente sans (trop) devoir se poser la question de savoir exactement à quel type d'objet on a affaire.

    Ce patron de conception est régulièrement utilisé dans le domaine de l'IHM car on peut estimer que, qu'il s'agisse de la fenêtre principale, d'un menu, ou de n'importe quel élément visuel utilisable, nous avons "simplement" affaire à... un élément visuel, susceptible d'en contenir d'autres... ou non.

    Seulement, alors que le "sens classique" dans lequel les informations sont généralement transmises dans une relation de contenant à contenu va du contenant vers le contenu, il n'est pas rare, surtout dans le domaine de l'IHM (mais pas uniquement) que le sens du passage de l'information doive être inversé et que le contenu doive être en mesure d'envoyer des informations à son contenant.

    Seulement, pour y arriver, il faut bien... disposer d'une référence (au sens générique, et non au sens C++ du terme ) vers le contenant, pour autant qu'il y en ait un.

    Et comme il est malgré tout impensable de transmettre cette information de manière systématique à toutes les fonctions membres, la meilleure solution consiste à déclarer un membre du type du contenant dans le contenu.

    Mais comme il est impossible de faire rentrer quelque chose qui prend plus d'espace mémoire que l'objet dans lequel on essaye de le faire entrer, et qu'il faut aussi être en mesure de déterminer s'il y a effectivement un contenant, le membre dans le contenu qui lui permettra de s'adresser au contenant ne peut être... qu'un pointeur.

    Comme, enfin, on conseille fortement de faire en sorte que tout objet soit "complet" et utilisable dés le moment de sa création (il n'est vraiment pas recommandé de devoir invoquer trente six mutateurs avant de pouvoir utiliser l'objet ) il est largement préférable d'initialiser le parent dés le constructeur
    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
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Pourquoi ne pas le faire avec une référence ?
    Le pointeur ne prend pas de la mémoire lui ?

    Merci d'avance à bientôt.

  6. #6
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Pourquoi ne pas le faire avec une référence ?
    Parce qu'un objet peut ne pas avoir de parent (c'est le cas par exemple des fenêtres principales, qui ne sont pas contenues dans une autre)
    Or un pointeur peut être nul mais pas une référence

  7. #7
    Invité
    Invité(e)
    Par défaut
    Ok j'ai compris l'idée globale c'est vachement bien pensé en fait. De plus je ne savais pas qu'un objet d'une classe de base prenait plus d'espace mémoire qu'un objet d'une classe dérivée.

  8. #8
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par gizmo27 Voir le message
    De plus je ne savais pas qu'un objet d'une classe de base prenait plus d'espace mémoire qu'un objet d'une classe dérivée.
    Cela ne peut pas être possible, puisqu'une classe dérivée inclus la classe dont elle dérive ^^

  9. #9
    Invité
    Invité(e)
    Par défaut
    Koala a dit ceci :
    Citation Envoyé par koala01 Voir le message
    Mais comme il est impossible de faire rentrer quelque chose qui prend plus d'espace mémoire que l'objet dans lequel on essaye de le faire entrer
    on essaye de faire rentrer un objet de QObject (classe de base) dans un objet de QDérivée (classe dérivée) : j'ai compris que l'objet QObject prenait plus d'espace mémoire que l'objet QDérivée...
    J'ai sûrement mal compris quelque chose alors...

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Tu as très mal compris ce que j'essayais d'expliquer...

    Une classe de base prend, fatalement, moins d'espace mémoire que n'importe quelle classe qui en dérive, mais....

    Si tu as une classe Element qui agit comme le "contenu" et une classe Collection qui agit comme "contenant" d'un nombre fixe et clairement déterminé d'élément de type de Element, le code serait 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 Base
    {
        //...
    };
    class Element : public Base
    {
        // ...
    };
    ///sizeof(Element) >= sizeof(Base)
    class Collection /* : public Base */
    {
        //...
        private:
            Element[N]; //N est une constante connue à la compilation
    };
    //sizeof(Collection) >= sizeof(Collection) * N >= sizeof(Base) * N
    Element prenant moins d'espace en mémoire que Collection, il devient tout à fait impossible de placer sous forme de valeur un objet de type Collection dans element, simplement parce que l'on se retrouve face à un serpent qui se bouffe la queue: la taille de Collection dépend de la taille de Element, qui augmente elle-même de la taille de Collection, qui augmentera parce que la taille de Element vient de le faire (et ainsi de suite).

    Si tu veux mettre une référence (au sens général du terme) vers le contenant dans le contenu, tu dois donc veiller à ce que ce que tu essaye de placer dans le contenu nécessite un espace mémoire fixe et clairement défini.

    Les deux seules choses qui utilisent un espace mémoire fixe et clairement défini quel que soit le type d'objet référencé sont les pointeurs et les références (qui sont souvent implémentées, au niveau du code binaire exécutable, exactement de la même manière que les pointeurs ).

    Les différences principales entre les deux, c'est qu'un pointeur peut obtenir une valeur connue comme représentant l'absence d'objet référencé (NULL / nullptr dans la nouvelle norme), et que nous pouvons changer l'objet référencé (sous réserve qu'il soit de type compatible), alors que l'objet référencé par la référence a une garantie de non nullité, et qu'il nous est impossible de faire en sorte de changer l'objet référencé.
    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
    Invité
    Invité(e)
    Par défaut
    Merci pour la réponse.
    Je reviens avec une autre question : dans l'implémentation d'un constructeur j'ai ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Constr::Constr(bibi &a, bubu &b=bubu()){}
    Mon souci est au niveau de la compréhension du 2ème paramètre, soit :Je ne comprend pas cette ligne : que signifie-t-elle ?
    (je me dis que si l'on ne renseigne pas ce paramètre, le paramètre par défaut sera la référence sur b... mais comme on ne renseigne pas le paramètre alors une référence sur rien ça colle pas...)
    Merci d'avance. Bonne journée.
    Cordialement, Gizmo.

  12. #12
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Constr::Constr(bibi &a, bubu &b=bubu()){}
    Ici, comme tu l'as compris, bubu() est la valeur par défaut de la variable b (b étant de type bubu&). En fait, bubu() appelle le constructeur par défaut de la class bubu. Ce qui signifie donc, concrètement, que si tu ne fournis pas de 2nd paramètre lorsque tu vas appeler ce constructeur, b sera automatiquement crée en utilisant le constructeur par défaut de la classe bubu.

  13. #13
    Invité
    Invité(e)
    Par défaut
    ah bon d'accord... donc c'était bien ça... cool alors.
    merci pour la réponse. bonne journée à vous

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par r0d Voir le message
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Constr::Constr(bibi &a, bubu &b=bubu()){}
    Ici, comme tu l'as compris, bubu() est la valeur par défaut de la variable b (b étant de type bubu&). En fait, bubu() appelle le constructeur par défaut de la class bubu. Ce qui signifie donc, concrètement, que si tu ne fournis pas de 2nd paramètre lorsque tu vas appeler ce constructeur, b sera automatiquement crée en utilisant le constructeur par défaut de la classe bubu.
    Si ce n'est que cela devrait etre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Constr::Constr(bibi & a, bubu const & b=bubu()){}
    Pour a, cela n'a pas énormément d'importance, hormis que cela placera une restriction qu'il s'agit impérativement d'éviter pour b:

    il faut absolument fournir un objet existant en argument pour a car il n'y a pas moyen de créer une variable temporaire anonyme pour une référence non constante.

    tu ne pourrais donc, par exemple, pas écrire un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main
    {
        Constr c(bibi(/* parametres */, bubu(/* autres paramètres*/) );
        /* la suite */
        return 0;
    }
    La raison est simple: la norme estime que, comme tu ne pourra de toutes manières pas réutiliser la variable anonyme temporaire en dehors de la fonction lors de l'appel de laquelle elle est créée, il ne sert strictement à rien d'en permettre la modification
    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. [C#]Constructeur avec paramètre dans designer
    Par ClaudeBg dans le forum Windows Forms
    Réponses: 1
    Dernier message: 15/02/2009, 19h18
  2. [PHP 5.2] [POO] Constructeur avec paramètres et héritage
    Par yamayo dans le forum Langage
    Réponses: 4
    Dernier message: 11/01/2009, 20h40
  3. [Framework] [Core] bean et constructeur avec paramètre
    Par robert_trudel dans le forum Spring
    Réponses: 3
    Dernier message: 10/07/2008, 13h52
  4. [EJB Session] Constructeur avec paramètres ?
    Par DevTeam_ dans le forum Java EE
    Réponses: 23
    Dernier message: 07/05/2008, 12h07

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