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 :

[conception] spécialisation de paramètres de fonctions héritées


Sujet :

C++

  1. #1
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut [conception] spécialisation de paramètres de fonctions héritées
    Bonjour à tous,

    j'ai un petit problème de conception, et je ne sais pas trop comment le résoudre de façon élégante.

    J'ai une classe mère (virtuelle) IResponse et plusieurs classes filles qui l'implémentent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class IResponse
    {
    //...
    };
     
    class Response1 : public IResponse
    {
    // ...
    };
    Ensuiet, j'ai une classe mère (virtuelle) IRequest qui définit une fonction membre process().
    J'ai plusieurs classe filles qui implémentent IRequest:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class IRequest
    {
        //    [...]
        virtual int process() = 0;
    };
     
    class Request1 : public IRequest
    {
        //    [...]
        int process();
    }
    Jusqu'ici, tout va bien.
    Je voudrais maintenant que ma méthode process prenne un IResponse en paramètre, mais que ce paramètre soit spécialisé pour les spécialisations de IRequest::process.
    En gros, je voudrais faire ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class IRequest
    {
        //    [...]
        virtual int process(IResponse &response) = 0;
    };
     
    class Request1 : public IRequest
    {
        //    [...]
        int process(Response1 &response);
    }
    Le problème, c'est que si je fais ça, j'ai cru comprendre que je ne fais que surcharger process, mais que je ne l'implémente pas.

    Vous voyez ce que je cherche à faire? (c'est pas évident à expliquer)
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  2. #2
    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
    Je ne pense pas que cette "covariance sur une autre classe" soit possible.
    Si tu veux redéfinir la fonction virtuelle, tu seras obligé de downcaster (avec static_cast<> ou dynamic_cast<>, mais ni un cast C ni reinterpret_cast<>), ou bien de travailler seulement sur l'interface.

    Es-tu sûr d'avoir besoin d'accéder au type Request1 ?
    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.

  3. #3
    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
    Tu ne peux pas etre covariant sur les parametres, uniquement sur le type de retour.

    Si on est covariant sur les parametres, il faut verifier la coherence des types a l'execution. Tu peux utiliser dynamic_cast pour le simuler.

    Note: on peut etre contra-variant sur les parametres et conserver la possibilite d'une verification statique des types, mais ce n'est pas disponible en C++.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  4. #4
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Médinoc
    Es-tu sûr d'avoir besoin d'accéder au type Request1 ?
    Oui car je dois remplir les champs de Request1. Et ils sont différents de Request2.

    Citation Envoyé par Jean-Marc.Bourguet
    Tu ne peux pas etre covariant sur les parametres, uniquement sur le type de retour.
    Je pourrais donc faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class IRequest 
    {
      // [...]
      virtual IResponse* process() = 0; 
    }
    ;   
     
    class Request1 : public IRequest 
    {
      // [...]
      Response1* process(); 
    }
    ?
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  5. #5
    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 r0d
    Je pourrais donc faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class IRequest 
    {
      // [...]
      virtual IResponse* process() = 0; 
    }
    ;   
     
    class Request1 : public IRequest 
    {
      // [...]
      Response1* process(); 
    }
    ?
    Oui.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  6. #6
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Ok merci. Je vais faire comme ça alors. Mais j'ai l'impression que ce n'est pas trés "propre" comme façon de faire non?
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  7. #7
    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
    Si c'est pour allouer et initialiser, tu peux directement retourner une IResponse, si tu juges ça plus propre.
    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.

  8. #8
    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 r0d
    Ok merci. Je vais faire comme ça alors. Mais j'ai l'impression que ce n'est pas trés "propre" comme façon de faire non?
    Une classe derivee peut offrir des post-conditions plus forte que la classe de base (c'est la co-variance sur le resultat) et avoir besoin de pre-conditions plus faibles (c'est la contra-variance sur les parametres). Je ne vois pas en quoi ce n'est pas propre d'utiliser ce fait. Ce n'est pas different que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Request1 : public IRequest 
    {
      // [...]  
      IResponse* process() { return request1Process(); }
      Response* request1Process() {... }
    };
    et d'utiliser request1Process quand tu as une instance de Request1 (a part le comportement dispatche pour les classes deriviees de Request1).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  9. #9
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Ok.

    à vous
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 09/06/2011, 15h29
  2. Paramètres de fonction : pointeurs ou valeurs ?
    Par Xandar dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 30/11/2005, 16h50
  3. Retrouver les valeurs des paramètres des fonctions d'une DLL
    Par Bernard Martineau dans le forum Langage
    Réponses: 6
    Dernier message: 08/11/2005, 10h42
  4. Paramètre de fonction
    Par Reynald dans le forum Débuter
    Réponses: 6
    Dernier message: 05/01/2005, 21h48
  5. Réponses: 4
    Dernier message: 13/08/2004, 18h39

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