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 :

Appel automatique du constructeur d'une classe mère?


Sujet :

C++

  1. #1
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut Appel automatique du constructeur d'une classe mère?
    Bonsoir,

    J'ai plusieurs questions! Si j'hérite une classe B d'une classe A et que cette classe A, la classe mère, possède un constructeur mais que sa classe fille, la classe B, n'en possède pas... Est-ce que le constructeur de la classe mère sera appelé automatiquement lors de la création d'un objet de type B?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class A
    {
    public:
       A(...) { /* ...*/} //constructeur
    };
     
    class B: public A
    {
    public:
       //pas de constructeur
    }
    Ou dois-je spécifier un constructeur à la classe B qui appel le constructeur de la classe mère:
    Merci d'avance!
    Rodrigue

  2. #2
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Si B n'a pas de constructeur , il faut que A ait un moins un constructeur par défault.

    En effet, si A en a constructeur par défault ; pas de problème ca compile , les objets sont iniatilisé par défault.
    Mais si A n'en a pas , ca compile pas et tu est obligé de définir un constructeur pour B pour envoyer des arguments à A.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  3. #3
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    Oui c'est vrai que c'est logique que c'est le constructeur par défaut de la classe mère qui sera appelée...

    Donc si ma classe A ne possède pas de constructeur par défaut mais par exemple un constructeur de ce type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    A(int u, float v) {/* ... */}
    Il faut absolument que je redéfinisse un constructeur similaire à la classe B:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    B(int u, float v): A(u,v) {/* ... */}
    Rodrigue

  4. #4
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Oui.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  5. #5
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    Ok, merci beaucoup!
    Rodrigue

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2007
    Messages : 15
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Rodrigue Voir le message
    Oui c'est vrai que c'est logique que c'est le constructeur par défaut de la classe mère qui sera appelée...

    Donc si ma classe A ne possède pas de constructeur par défaut mais par exemple un constructeur de ce type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    A(int u, float v) {/* ... */}
    Il faut absolument que je redéfinisse un constructeur similaire à la classe B:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    B(int u, float v): A(u,v) {/* ... */}
    Non, tu pourrais aussi définir un constructeur de B comme ca à la place:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    B(int u): A(u,0.0) {/* ... */}
    [/

  7. #7
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    C'est du détail d'implémentation.
    ce qui ne change pas , c'est qu'il est obliger de déclarer un constructeur pour sa classe B.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  8. #8
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    C'est du détail d'implémentation.
    ce qui ne change pas , c'est qu'il est obliger de déclarer un constructeur pour sa classe B.
    Oui, tout à fait . Je trouve que les constructeurs des classes mères devraient être s'ils ne sont pas "surchagés" (j'entends par là avoir la même déclaration) disponibles dans les classes filles...
    Rodrigue

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

    Informations professionnelles :
    Activité : aucun

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

    Ceci dit, un constructeur qui ne prend aucun paramètre obligatoire est, aussi, un constructeur par défaut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class A
    {
        public:
            A(float u=0.0, float v=0.0):u(u), v(v){}
            virtual ~A(){}
            /*...*/
        private:
            float u;
            float v;
    };
    permet tout à fait la création des trois objets qui suivent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    A obj1; /* les valeurs fournies sont d'office 0.0 et 0.0 */
    A obj2(1.56); /* v vaut d'office 0.0 */
    A obj3(1.56,3.98):/* les deux valeurs sont fournies */
    Si tu estime cohérent que la part de l'application de permettre que ces trois objets soient créés, la technique facilite fortement la vie (et surtout diminue le nombre de lignes à te palucher ), autrement, il faudra sans doute envisager de déclarer le constructeur ne prenant aucun paramètre en protégé...

    De cette manière, tu peux envisager de laisser le compilateur placer son propre constructeur par défaut à la classe B qui hérite de A.

    Cependant, il ne faut pas oublier que, de manière générale, sur les "big four" (constructeur par défaut, constructeur par copie, destructeur et opérateur d'affectation) - que le compilateur est capable de fournir s'il n'en trouve pas la déclaration ou une déclaration qui "fait office" de, comme pour le cas du constructeur par défaut - il est largement conseillé de définir soi-même au minimum les trois premiers
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    Ok, merci pour ces rappels !

    Il faudra sans doute envisager de déclarer le constructeur ne prenant aucun paramètre en protégé...

    De cette manière, tu peux envisager de laisser le compilateur placer son propre constructeur par défaut à la classe B qui hérite de A.
    Je ne comprends pas bien c'est que tu as voulu expliquer.
    Pour moi, ça ne change rien de placer le constructeur en mode protected vu que B hérite de A (la classe B a donc accès au membre protégé de la classe A)?
    Rodrigue

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Pour la classe B, cela ne change rien: elle a accès au constructeur par défaut, et il est d'ailleurs impératif qu'elle y ait accès .

    Par contre, cela interdit d'appeler le constructeur par défaut de A directement, ainsi, avec les classes
    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
    class
    {
     
        public:
            A(float u, float v):u(u), v(v){}
            virtual ~A(){}
            /*...*/
        protected:
            A():u(0),v(0){}
        private:
            float u;
            float v;
    };
    class B:publicA
    {
        /* pas de constructeur pour B
         * ...
         */
    };
    on force l'utilisation du constructeur prenant deux paramètres si on veut déclarer une instance de A (nous sommes bien dans le cadre où l'on ne juge pas opportun de pouvoir déclarer les trois objets dans l'intervention précédente )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int main()
    {
     
        A obja;//erreur: A::A() inaccessible
        A obja2(1.32, 3.54); //ok
        B objb; //ok, accede à A::A() via B::B()
    }
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    En fait, et pour être précis, le fait de rendre tous les constructeurs (et idéalement alors l'opérateur d'assignation) protégé rend une classe aussi sûrement non instanciable en tant que telle que pourrait le faire la présence d'une fonction virtuelle pure.

    Par contre, l'instanciation des classes dérivées reste autorisée
    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

  13. #13
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    D'accord, merci beaucoup j'ai bien compris le principe! C'est une bonne astuce
    Rodrigue

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

Discussions similaires

  1. Appel d'un constructeur d'une classe Java
    Par Invité dans le forum MATLAB
    Réponses: 2
    Dernier message: 09/02/2015, 09h31
  2. Réponses: 7
    Dernier message: 27/01/2009, 08h25
  3. [POO]Appelé une méthode d'une classe mère
    Par LE NEINDRE dans le forum Langage
    Réponses: 2
    Dernier message: 14/12/2005, 14h44
  4. Réponses: 5
    Dernier message: 20/11/2005, 11h15
  5. Réponses: 3
    Dernier message: 06/11/2005, 18h02

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