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 & méthode virtuelle pure


Sujet :

C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Juin 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 5
    Points : 2
    Points
    2
    Par défaut Constructeur & méthode virtuelle pure
    Bonjour,

    après deux jours passés à écumer internet à la recherche d'un moyen pour conjuguer constructeur & méthode virtuelle pure en C++, je viens appeler à l'aide ici.

    Voici une description de mon problème :

    dans le cadre du développement d'une application multi-tâche, je cherche le moyen de créer une classe générique pour manipuler une application gérant plusieurs choses comme les logs.

    Partant de là, je souhaite pouvoir dans le constructeur de ma classe, laisser à son utilisateur la possibilité d'exécuter certaines actions par le biais de méthodes prédéfinies mais non-implémentées.

    Le problème est que, venant de Java, j'ai commencé par bêtement créer des méthodes virtuelles pures appelées dans le constructeur. Malheureusement, l'ordre de création des objets en C++ est différent de celui de Java, et je me retrouve le bec dans l'eau à ne pas savoir comment obliger le constructeur de la classe mère à travailler avec les méthodes surchargées de la classe fille...

    J'ai réussi à vaguement discerner dans les résultats que le pattern factory pourrait répondre à mon problème, mais je ne vois pas bien comment...


    Merci pour votre aide !

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Salut,
    Citation Envoyé par Mobleu Voir le message
    Bonjour,

    après deux jours passés à écumer internet à la recherche d'un moyen pour conjuguer constructeur & méthode virtuelle pure en C++, je viens appeler à l'aide ici.

    Voici une description de mon problème :

    dans le cadre du développement d'une application multi-tâche, je cherche le moyen de créer une classe générique pour manipuler une application gérant plusieurs choses comme les logs.

    Partant de là, je souhaite pouvoir dans le constructeur de ma classe, laisser à son utilisateur la possibilité d'exécuter certaines actions par le biais de méthodes prédéfinies mais non-implémentées.

    Le problème est que, venant de Java, j'ai commencé par bêtement créer des méthodes virtuelles pures appelées dans le constructeur. Malheureusement, l'ordre de création des objets en C++ est différent de celui de Java, et je me retrouve le bec dans l'eau à ne pas savoir comment obliger le constructeur de la classe mère à travailler avec les méthodes surchargées de la classe fille...
    C'est bien simple: tu ne peux pas...

    L'ordre de création des objets se fait dans l'ordre d'héritage: d'abord la classe mère (qui ne connait qu'elle) puis les classes dérivées (qui connaissent la classe mère).

    Tant que l'objet "le plus dérivé" n'a pas été construit, il est strictement impossible de faire en sorte qu'un des comportements qui lui est spécifique soit utilisé.

    Si tu déclares une fonction virtuelle (non pure) dans la classe de base, tu peux appeler cette fonction dans le constructeur de la classe mère, mais ce sera alors le comportement spécifique à la classe mère qui sera pris en compte
    J'ai réussi à vaguement discerner dans les résultats que le pattern factory pourrait répondre à mon problème, mais je ne vois pas bien comment...
    En fait, le pattern factory permet "uniquement" de n'avoir pas à s'inquiéter du type réel de l'objet que l'on va créer, afin de le considérer uniquement comme étant du type de la classe mère.

    Autrement dit, il va permettre, lorsque tu l'utilises et que tu as des classes B, C, D,..., ZZ qui héritent de la classe A, de ne pas avoir à te soucier de savoir si l'objet réellement construit est de type B,C, D, ..., ZZ, mais de le considérer comme s'il s'agissait d'un objet de type A, et donc de n'avoir une dépendance que vis à vis de ce type A, à l'exclusion de tout autre. (la seule dépendance avec les types B, C, D,..., ZZ se trouvant au niveau de la fabrique elle-même).

    Si tu veux qu'un comportement polymorphe, disponible dans l'interface publique de A, soit appelé sur tous les objets que la fabrique peut te renvoyer, tu peux soit faire en sorte que la fabrique appelle le comportement en question après avoir terminé de construire l'objet de type réel, mais avant de le renvoyer, soit appeler explicitement le comportement en question au départ de l'objet renvoyé par la fabrique dans la fonction qui reçoit l'objet créé, et ce, malgré le fait qu'il soit connu comme étant du type de base (le polymorphisme jouant alors )

    Le fait d'appeler ce comportement au niveau de la fabrique permet, tu l'auras compris, d'avoir la certitude qu'il sera d'office appelé, mais il faut alors se poser la question de savoir ce qui pourrait arriver si, par erreur, l'utilisateur rappel le dit comportement de son coté.

    Si cela risque de poser problème, l'idéal est sans doute de passer par une fonction virtuelle dans l'accessibilité privée et par une déclaration d'amitié de la fabrique envers la classe de base, et pour autant que l'objet créé soit connu de la fabrique comme étant du type de base (parce que l'amitié n'est ni transitive ni héritée), le polymorphisme faisant le reste
    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

  3. #3
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Points : 1 475
    Points
    1 475
    Par défaut
    Citation Envoyé par Mobleu Voir le message
    venant de Java, j'ai commencé par bêtement créer des méthodes virtuelles pures appelées dans le constructeur.
    Même en java, c'est pas l'idée du siècle, amha...certes le late binding permet que la bonne méthode soit appelée, mais certaines caractéristiques de ta classe effective ne sont pas en place, vu que en java aussi, c'est le constructeur de la classe mère qui est appelé en premier. Autrement dit en faisant ça tu ouvres la porte à des comportement favorables aux bugs car contre-intuitifs...

  4. #4
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Juin 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Bon j'ai trouvé une solution pour contourner en partie le problème.

    Elle ne fonctionne que parce que les méthodes que je souhaite fournir à l'utilisateur sont indépendantes de tout contexte du début à la fin.

    J'ai finalement déporté les méthodes en question dans une nouvelle classe que j'ai appelée ClassInitializer.

    Ensuite, j'ai modifié la classe pour la gestion des applications de manière à en faire un template. Du coup, lorsque l'utilisateur voudra créer un objet application, il précisera dans le constructeur le type d'objet fournissant les méthodes : soit l'objet de base fourni avec la classe, soit un objet dérivé de cet initialiseur.

    Du coup, dans le constructeur, je suis alors capable d’instancier un initialiseur et d'appeler les méthodes fournies.

    Bien évidemment, cette astuce ne fonctionne que parce que l'initialiseur n’interagit pas avec la classe fille qui, lors de l'appel du constructeur de la classe mère, n'est pas encore créée.

    Il doit être possible de rajouter des fonctions à l'intialiseur en en faisant une inner-class de la classe mère, mais je ne me suis pas encore penché sur le problème...

    Attention ! Il faut savoir que si vous utilisez Qt, et que la classe mère template appelle la macro QOBJECT, le compilo s'énerve. Pour contourner le problème, il faut créer une troisième classe, dérivée de la classe mère, qui fera office de surcouche template à la classe mère.

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

Discussions similaires

  1. méthode virtuelle pure et héritage
    Par Invité dans le forum Langage
    Réponses: 3
    Dernier message: 20/07/2009, 23h12
  2. Réponses: 3
    Dernier message: 17/09/2008, 14h52
  3. Réponses: 15
    Dernier message: 05/07/2007, 02h29
  4. Réponses: 23
    Dernier message: 16/03/2007, 21h21
  5. Problème avec une méthode virtuelle pure
    Par Burckel dans le forum C++
    Réponses: 4
    Dernier message: 05/12/2006, 14h00

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