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 :

Initialisation d'un constructeur privé


Sujet :

C++

  1. #1
    Membre habitué Avatar de robinsondesbois
    Homme Profil pro
    Etudiant
    Inscrit en
    Avril 2012
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : Etudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 171
    Points : 173
    Points
    173
    Par défaut Initialisation d'un constructeur privé
    Bonjour,

    J'ai une classe avec un constructeur par défaut privé et je souhaiterais l'initialiser avec un constructeur par paramètre via un constructeur d'une autre classe.

    Le code parle mieux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class A
    {
    private :
      int i; 
      A(){}
    public:
      A(int i) {this->i = i;}
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include "A.h"
     
    class B
    {
    private :
      A a;
      B(){}
    public:
      B(int i) : a(i){}
    };
    Ce code génère une erreur. "A is private".

  2. #2
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Bonjour

    Ton constructeur par défaut de B a besoin du constructeur par défaut de A. Une solution est de ne pas l'appeler.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class B
    {
      // ...
      B() : a(0) { } // B(){}
      // ...
    };

  3. #3
    Membre habitué Avatar de robinsondesbois
    Homme Profil pro
    Etudiant
    Inscrit en
    Avril 2012
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : Etudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 171
    Points : 173
    Points
    173
    Par défaut
    Bien vu !!
    Merci beaucoup

  4. #4
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Tout constructeur appelle les constructeurs de chacun des membres de la classe (après ceux de ses classes de bases).

    Si certains ne sont pas précisés, ce sont les constructeurs par défaut qui seront appelés (par défaut, justement).

    Comme le dit Ehonn, quand le constructeur par défaut est privé, il faut obligatoirement appeler un constructeur (dans la liste d'initialisation).
    Voila pour les détails
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  5. #5
    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,

    A vrai dire, il y a vraiment peu de cas dans lesquels un constructeur nécessite d'être privé, surtout si d'autres constructeurs ne le sont pas. La raison est simple : cela n'a, purement et simplement, aucun sens!.

    En effet, le propre de l'accessibilité privée est de faire en sorte que seules les fonctions membres de la classe puissent accéder à ce qui se trouve dans cette accessibilité. Or, pour pouvoir disposer d'une fonction membre, il faut disposer d'une instance du type de la classe et, pour disposer de cette instance, il faut pouvoir la construire. Si on ne sait pas construire l'instance de la classe, on ne peut tout simplement pas appeler les fonctions membres de cette classe, et la classe s'avère donc totalement inutilisable (*)

    Le seul cas où il serait "cohérent" d'avoir un constructeur privé (mais rien que lui, alors) serait de prévoir "autre chose" qui dispose de suffisamment de droit pour accéder à ce constructeur, comme une fonction (ou une classe) amie par laquelle nous serions obligés de passer pour pouvoir disposer d'une instance de la classe

    (*) Alors, oui, bien sur, il y a toujours la possibilité de créer une fonction statique ("create" ) qui disposera des droits suffisants pour appeler le constructeur. Mais la question est alors : si c'est, au final, pour nous donner accès à une fonction (publique!!!) statique qui nous renverra une instance de la classe, pourquoi ne pas utiliser la fonction qui est sensé faire cela par nature en nous forçant à passer par une fonction tout ce qu'il y a de plus synthétique
    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

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Mais la question est alors : si c'est, au final, pour nous donner accès à une fonction (publique!!!) statique qui nous renverra une instance de la classe, pourquoi ne pas utiliser la fonction qui est sensé faire cela par nature en nous forçant à passer par une fonction tout ce qu'il y a de plus synthétique
    Je dirais pour forcer un passage par un allocateur spécifique (ce qui au passage, interdit de construire l'objet en variable locale), ou passer des paramètres auxquels l'appelant n'est pas censé avoir accès, ou pour gérer un singleton...
    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.

  7. #7
    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
    Je suis d'accord qu'il peut y avoir des cas particuliers dans lesquels il est intéressant de le faire

    Cependant :
    • Tu sais ce que je pense du singleton
    • un allocateur sera -- pour respecter SRP -- de préférence transformé en fabrique
    • La modification des paramètres reçus par la fonction statique en paramètre attendus par le constructeur pourrait tout aussi bien être transférée à une fabrique (qui, pour la cause, serait déclarée amie de la classe )



    Comprend bien que ce n'est pas le fait d'avoir un constructeur privé qui m'ennuie... C'est le fait d'avoir une fonction statique "à la place" de ce constructeur dans l'accessibilité publique
    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

  8. #8
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Je rajouterai juste à ce qui a été dit qu’avant C++11, il était coutume de mettre un constructeur privé pour rendre l’objet non-copiable ou non default-constructible. Donc il est tout à fait possible de rencontrer ce cas de figure dans du code existant.

    De nos jours, on privilégiera la syntaxe

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 20/04/2008, 20h12
  2. Initialiser tableau class constructeur
    Par dédé dans le forum C++
    Réponses: 3
    Dernier message: 21/11/2006, 13h43
  3. Réponses: 9
    Dernier message: 31/07/2006, 21h19
  4. Réponses: 6
    Dernier message: 26/06/2006, 23h49
  5. [JUnit] [Test][Débutant] Constructeur privé
    Par Shabata dans le forum Tests et Performance
    Réponses: 2
    Dernier message: 12/01/2006, 15h45

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