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

Langage C++ Discussion :

Classe agissant sur sa dérivée


Sujet :

Langage C++

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 60
    Points : 71
    Points
    71
    Par défaut Classe agissant sur sa dérivée
    Bonjour,

    Dans le cadre du développement d'une bibliothèque, je suis tombé sur un os assez costaud. Voici une description du problème, si quelqu'un a une idée :

    J'ai une classe A qui contient un membre v.
    J'ai une classe B qui hérite de A à un certain niveau (telles que pour b de type B, b.A::v est accessible publiquement).

    Je veux écrire une classe template C<T, n> telle que si B hérite de C<B, n>, alors la construction d'un objet b de type B assigne n à b.A::v.

    Pour l'instant, j'ai trouvé la solution suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    struct A { int v; };
    template<typename D, int n>
    struct C {
      C() {
        D* dhis = static_cast<D*>(this);
        A* ahis = static_cast<A*>(this);
        ahis->v = n;
      }
    };
    Ce code fonctionne bien dans la plupart des cas, mais il y a un hic dans le cas d'héritage virtuel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // le code précédent
    struct X: A { virtual ~X() {} };
    struct B : virtual X, C<B, 13> {};
    En effet, la construction d'une instance de B segfaute.
    Quelqu'un aurait-il une idée sur un moyen de généraliser ce dispositif ?

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Ça ne te tente pas, l'utilisation des constructeurs ?

  3. #3
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 60
    Points : 71
    Points
    71
    Par défaut
    La procédure qui assigne b.A::v est bien située dans le constructeur de C.

    Le but est de faire en sorte que C<> agisse de manière parfaitement transparente pour B, donc notamment pas de code dans le constructeur de B.

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Je dois avouer que je suis un peu paumé dans ton graphe d'héritage avec A, B, C et X.

  5. #5
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par k1000 Voir le message
    Le but est de faire en sorte que C<> agisse de manière parfaitement transparente pour B, donc notamment pas de code dans le constructeur de B.
    Au final le but serait d'avoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    struct B : /* virtual */ A, /* private */ C<B, 13> {
     
    };
    Au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    struct B : /* virtual */ A {
    	B() : A(13) { }
    };
    ?

    Ca me semble une utilisation abusive des templates, ça n'apporte à priori rien, mais augmentera certainement le temps de compilation et la complexité du code.

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    J'ai du mal à comprendre ce que tu cherches à obtenir, et donc à t'orienter vers une solution.

    Aurais-tu un cas d'usage qui justifie le besoin que tu exprimes (et que j'ai du mal à saisir) ?

  7. #7
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 60
    Points : 71
    Points
    71
    Par défaut
    Citation Envoyé par Iradrille Voir le message
    Au final le but serait d'avoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    struct B : /* virtual */ A, /* private */ C<B, 13> {
     
    };
    Au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    struct B : /* virtual */ A {
    	B() : A(13) { }
    };
    ?
    Oui, c'est bien ça.

    Citation Envoyé par Iradrille Voir le message
    Ca me semble une utilisation abusive des templates, ça n'apporte à priori rien, mais augmentera certainement le temps de compilation et la complexité du code.
    Je suis d'accord que c'est un capillotracté comme utilisation (c'est d'ailleurs pour ça que problème).

    En fait ce pattern me sert dans une bibliothèque :
    - je fournis C<>, qui est en réalité une assez grosse classe
    - A et B sont écrites par l'utilisateur (donc je n'ai pas la possibilité d'ajouter un argument au constructeur de A)

    Je souhaite donc être le moins intrusif possible.

    Citation Envoyé par oodini Voir le message
    Aurais-tu un cas d'usage qui justifie le besoin que tu exprimes (et que j'ai du mal à saisir) ?
    Si tu veux la petite histoire : le membre A::v (d'un type bien plus complexe que int), sert en fait d'identifiant de la classe. Cet identifiant est ensuite utilisé pour faire une sorte de switch sur le type dynamique de l'objet créé (de manière plus efficace qu'une chaîne de dynamic_cast, et _sans_ avoir besoin de rajouter des fonctions virtuelles).
    Je me rapatrierai sur une autre implémentation si je peux démontrer que c'est impossible. Mais pour l'instant, c'est le design le plus performant que j'aie.

  8. #8
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    OK.

    À présent, réexplique-nous cette histoire de membre v, à la lumière de ton dernier message.

  9. #9
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 60
    Points : 71
    Points
    71
    Par défaut
    Voir mon message précédent (édité pour l'étoffer alors que tu répondais )

    Après tout, peu importe ce que j'en fais.
    Cette question est surtout histoire de savoir si c'est faisable ?

  10. #10
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par k1000 Voir le message
    Si tu veux la petite histoire : le membre A::v (d'un type bien plus complexe que int), sert en fait d'identifiant de la classe. Cet identifiant est ensuite utilisé pour faire une sorte de switch sur le type dynamique de l'objet créé (de manière plus efficace qu'une chaîne de dynamic_cast, et _sans_ avoir besoin de rajouter des fonctions virtuelles).
    Je me rapatrierai sur une autre implémentation si je peux démontrer que c'est impossible. Mais pour l'instant, c'est le design le plus performant que j'aie.
    Hmmm.... L'utilisation d'un switch est rarement justifiée.
    Je comprend ton envie/besoin d'éviter la virtualité (bien que tu veuilles utiliser un héritage virtuel...), mais as-tu étudié le polymorphisme statique (CRTP) ?
    Ou les classes de trait ?

  11. #11
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 60
    Points : 71
    Points
    71
    Par défaut
    Oui, je connais tout ça.

    J'ai finalement trouvé seul une réponse à ma question d'origine. Dans le cas général, le constructeur de C<> ne peux pas connaître l'adresse des membres de A.

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

Discussions similaires

  1. Utiliser des packages ou des classes présents sur le net
    Par lionrouge dans le forum Général Java
    Réponses: 2
    Dernier message: 27/09/2006, 06h09
  2. [WebForms]Evénements agissant sur des contrôles
    Par dj_lil dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 14/06/2006, 17h47
  3. Réponses: 6
    Dernier message: 21/05/2006, 20h37
  4. [PHP-JS] form agissant sur 2 pages
    Par splouf dans le forum Langage
    Réponses: 3
    Dernier message: 16/01/2006, 11h35
  5. Glut / Class / Pointeur sur fonction
    Par areS. dans le forum GLUT
    Réponses: 5
    Dernier message: 02/12/2005, 20h50

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