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 :

Classe abstraite et constructeurs


Sujet :

C++

  1. #1
    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 Classe abstraite et constructeurs
    Salut,

    Je me pose actuellement une question qui pourrait parraitre saugrenue.

    On nous apprend que quand on crée une classe, il est préférable de définir un constructeur par défaux et un par copie, que sinon le compilateur va placer les siens, et que ca risque de poser problème, soit.

    Mais, qu'en est-il des classes abstraites?

    En effet, une classe abstraite ne sera JAMAIS instensiée, et, lors de la création de classes dérivées, nous devrons insérer les parametres (éventuellement) nécessaires à la classe abstraite pour pouvoir appeler son constructeur.

    La question est donc, en réalité, "si un classe abstraite a besoin de parametres, est-il nécessaire de prévoir un constructeur de copie?" (le constructeur par défaut, la question ne se posant pas tellement finalement)

    Merci d'avance à tous ceux qui pourront m'éclairer là dessus
    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

  2. #2
    Membre expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Points : 3 344
    Points
    3 344
    Par défaut
    Citation Envoyé par koala01
    On nous apprend que quand on crée une classe, il est préférable de définir un constructeur par défaux et un par copie, que sinon le compilateur va placer les siens, et que ca risque de poser problème, soit.
    Tout dépend de ce que ta classe contient... Il peut arriver que le construsteur par défaut créé par le compilo soit tout de même suffisant.

    Citation Envoyé par koala01
    Mais, qu'en est-il des classes abstraites?

    En effet, une classe abstraite ne sera JAMAIS instensiée, et, lors de la création de classes dérivées, nous devrons insérer les parametres (éventuellement) nécessaires à la classe abstraite pour pouvoir appeler son constructeur.
    En fait, une classe abstraite ne peut pas être instanciée directement. Mais quand tu instancies une classe dérivée de ta classe abstraite, ça commence par "construire" la classe abstraite avant de passer à la partie spécifique de ta classe dérivée. Donc pour une classe abstraite, je pense qu'il faut créer les constructeurs / desctructeurs de la même façon que pour une classe instanciable.

  3. #3
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Comme pourrait te le dire Luc, hiérarchie de classes (à but polymorphique) et sémantique de valeur vont rarement de paire. Donc à moins que tu n'aies réellement besoin de copier tes instances dérivées, ne cherche pas à définir un constructeur par copie. Si tu n'en n'as pas besoin il vaut même mieux l'interdire (tout comme l'opérateur d'affectation).

  4. #4
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par koala01
    On nous apprend que quand on crée une classe, il est préférable de définir un constructeur par défaux et un par copie, que sinon le compilateur va placer les siens, et que ca risque de poser problème, soit.
    Bizarre, la majorité de mes classes déclarent (en privé) mais ne définissent pas de constructeur de copie.

    Mais, qu'en est-il des classes abstraites?
    Les classes abstraites sont faites pour être utilisées avec du polymorphisme, et le polymorphisme se marie très mal avec une sémantique de valeur, donc avec la copie. Donc sauf rarissimes exceptions les classes abstraites désactivent le constructeur de copie.

    Le constructeur par défaut ne pose en général que peu de problème: c'est assez rare que la version du compilateur convienne et qu'en plus il n'y a pas d'autre constructeur (puisque le compilateur ne génère un constructeur par défaut que si aucun autre constructeur n'est déclaré).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  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
    Citation Envoyé par Eusebe
    En fait, une classe abstraite ne peut pas être instanciée directement. Mais quand tu instancies une classe dérivée de ta classe abstraite, ça commence par "construire" la classe abstraite avant de passer à la partie spécifique de ta classe dérivée. Donc pour une classe abstraite, je pense qu'il faut créer les constructeurs / desctructeurs de la même façon que pour une classe instanciable.
    On se comprend bien là dessus, même si je ne l'avais pas explicitement dit, mais le constructeur de la classe abstraite n'a besoin que des paramètres (s'il y en a) qui sont nécessaires à sa construction.

    Citation Envoyé par Jean-Marc.Bourguet
    Bizarre, la majorité de mes classes déclarent (en privé) mais ne définissent pas de constructeur de copie.
    C'est une solution, mais, dans quelle mesure n'est-ce pas uniquement pour éviter que le compilo ne rajoute de lui-même un constructeur de copie dont tu n'a (sans doute) nullement besoin et qui serait sans doute placé en public?

    Citation Envoyé par Jean-Marc.Bourguet
    Les classes abstraites sont faites pour être utilisées avec du polymorphisme, et le polymorphisme se marie très mal avec une sémantique de valeur, donc avec la copie. Donc sauf rarissimes exceptions les classes abstraites désactivent le constructeur de copie.
    Ca, par contre, c'est effectivement l'argument qui me faisait déjà pencher vers la désactivation du constructeur de copie
    Citation Envoyé par Laurent Gomila
    Comme pourrait te le dire Luc, hiérarchie de classes (à but polymorphique) et sémantique de valeur vont rarement de paire. Donc à moins que tu n'aies réellement besoin de copier tes instances dérivées, ne cherche pas à définir un constructeur par copie. Si tu n'en n'as pas besoin il vaut même mieux l'interdire (tout comme l'opérateur d'affectation).
    Je suivais effectivement un raisonnement fort similaire, bien que non dit explicitement.

    Quelque part vous avez tous trois confirmé ce que je préssentais, même si ma question était quelque peu évasive.

    Je vous en remercie grandement, et considère le sujet comme clot (à moins que d'autres n'aient des arguments différents)
    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 Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Citation Envoyé par Laurent Gomila
    Comme pourrait te le dire Luc
    C'est cool, on peut partir en vacances sans se soucier des forums

    Au cas où, pour un des mes plugins-wizards-générateur-de-code pour vim, j'ai distingué quatre cas de figure, les plus "extrêmes" et scolaires :
    - classe à sémantique de valeur
    - classe d'objet vivant sur la pile, mais à sémantique ni de valeur ni d'entité
    - classe à sémantique d'entité dont les instances sont clonables
    - classe à sémantique d'entité dont les objets ne sont même pas clonables

    A partir de là, j'ai des recettes de cuisine toutes prêtes pour les divers constructeurs, operateur d'affectation, et destructeur requis dans chaque cas de figure.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  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
    A vrai dire, ma question rentre dans le cadre d'un projet relativement complexe...

    Je me retrouve avec +/- 18 à 20 classes.

    L'idée de base, c'est que, dans ces 18 à 20 classes, il y en a 16 à 18 dont le seul but est de servir de membre "à la classe de niveau supérieur", et que chaque classe doit etre en mesure d'accéder "à la classe de niveau supérieur" dont elle est membre, en sachant qu'une classe donnée peut très bien s'avérer etre membre de plusieurs autres classes...

    Pour corser le tout, ces 18 à 20 classes doivent disposer de méthodes polymorphiques propres au projet, et la creation de template n'est pas adaptée (ou du moins, pour une grande partie des classes), car le nombre et le type des membres est beaucoup trop variable, déjà rien que si l'on ne regarde que les membres qui seraient d'un type de base (ceux de la STL inclus)

    Bref, je me retrouve avec la nécessité de disposer de 2 ou 3 interfaces pour pouvoir en faire dériver toutes les autres classes du projet...

    Le tout, en sachant que la partie du projet dont je parle devrait tout juste me permettre de gérer les données, en ce, compris la persistance de celles-ci, de manière la plus portable possible, et avant même d'y intégrer une quelconque interface graphique

    Il s'agit donc bel et bien de classes abstraite, vu qu'on est dans le stricte cadre du polymorphisme.

    L'astuce, c'est que je gardais en tete la "regle des grand trois": constructeur par défaut, constructeur par copie et opérateur d'assignation sont obligatoires, ainsi que l'avertissement du "si vous ne déclarez pas l'un de ces trois, le compilateur en mettra un générique pour vous, qui risque de ne pas vous convenir".

    Je suis bien d'accord avec le fait (c'est la caractéristique première des classes abstraite ) qu'aucune des interfaces ne peut etre instanciée directement, qu'elle ne le seront jamais que grace à l'appel de leur constructeur au sein des constructeurs des classes dérivées.

    C'est la raison pour laquelle je me posais sérieusement la question de savoir s'il était judicieux (ou non) d'au moins déclarer le constructeur par copie et l'opérateur d'assignation pour ces interfaces, et, si oui, de l'accessibilité à leur donner.

    Accessoirement, comme, normalement, "il n'est pas prévu dans le projet" de pouvoir copier les classes dérivées, le débat pourrait se répercuter sur elles, mais de manière beaucoup moins importante.
    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. Base : Classe abstraite et constructeur
    Par zax-tfh dans le forum ASP.NET
    Réponses: 10
    Dernier message: 28/12/2009, 23h57
  2. Réponses: 15
    Dernier message: 05/07/2007, 01h29
  3. Réponses: 2
    Dernier message: 18/04/2007, 13h34
  4. Réponses: 14
    Dernier message: 17/11/2006, 19h17
  5. pb constructeurs classes dérivant classe abstraite
    Par Cornell dans le forum Langage
    Réponses: 2
    Dernier message: 10/02/2003, 19h02

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