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 :

Spécialisation de template


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Octobre 2014
    Messages : 6
    Par défaut Spécialisation de template
    Bonjour à tous,
    J'aimerais savoir s'il était possible de créer l'architecture suivante:
    • Une classe mère abstraite et template A. Son type générique doit absolument hériter T.
    • Une classe abstraite T.
    • Des classe t, qui héritent chacune de T.
    • Des classes F. Chacune d'entre elle est une spécialisation, non pas de A, mais pour un certain t, de A<t>. Donc F est une implémentation de A pour un seul t.

    J'ai déjà essayé mais cela n'a pas été concluant... En effet, il doit y avoir un problème avec l'utilisation à la fois de polymorphisme statique (template) et dynamique(A est abstraite).
    Merci d'avance pour vos réponse!

  2. #2
    Invité
    Invité(e)
    Par défaut
    salut,

    ben si A<T> est abstraite, donc pour tout T, alors à fortiori A<t> est abstraite également...

    ce que tu peux faire c'est F qui hérite de A<T>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class F: public A<T>{};
    F<int> f;
    mais je sais pas trop ce que tu veux faire, notamment le coup de T abstraite, rien ne t'empêches de la construction de F de donner un t

  3. #3
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Citation Envoyé par Spirine Voir le message
    Bonjour à tous,
    J'aimerais savoir s'il était possible de créer l'architecture suivante:
    • Une classe mère abstraite et template A. Son type générique doit absolument hériter T.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    tempalte<class U>
    struct A
    { virtual void foo() =0; };
    Citation Envoyé par Spirine Voir le message
    • Une classe abstraite T.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    struct T
    { virtual void foo() =0; };
    Citation Envoyé par Spirine Voir le message
    • Des classe t, qui héritent chacune de T.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct t1 : T
    { };
     
    struct t2 : T
    { };
    Citation Envoyé par Spirine Voir le message
    • Des classes F. Chacune d'entre elle est une spécialisation, non pas de A, mais pour un certain t, de A<t>. Donc F est une implémentation de A pour un seul t.
    Je ne comprends pas ta phrase, mais je suppose que tu veux faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct F1 : A<t1>
    { };
     
    struct F2 : A<t2>
    { };
    Citation Envoyé par Spirine Voir le message
    J'ai déjà essayé mais cela n'a pas été concluant... En effet, il doit y avoir un problème avec l'utilisation à la fois de polymorphisme statique (template) et dynamique(A est abstraite).
    Merci d'avance pour vos réponse!
    Il existe en effet des limitations, mais pas pour faire ce que tu viens de mentionner à priori.

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Notes juste Flob, que je n'aurais pas utilisé le principe de la fonction virtuelle pure pour rendre la classe A<U> abstraite... Le compilateur a généralement énormément de mal à se rendre compte qu'une fonction déclarée comme virtuelle pure dans une classe template a bel et bien été définie dans les classes dérivée (ce qui devrait avoir pour résultat de rendre la classe dérivée instanciable )

    A vrai dire, comme le rôle des template est de générer du code spécifique à chaque spécialisation du paramètre template à la compilation, je ne sais même jamais si la norme autorise l'idée d'une fonction virtuelle dans une classe template destinée à servir de classe de base dans un hiérarchie

    Toujours est-il qu'une classe "abstraite" n'est rien d'autre qu'une classe qui ne peut pas être instanciée d'elle-même dans le sens où il faut qu'elle soit forcément instanciée au travers d'une des classes qui en dérivent. Il n'est donc pas forcément nécessaire de recourir à la technique de la fonction virtuelle pure pour y parvenir, car il "suffit" de placer le constructeur (et le destructeur, que l'on aura pris soin de ne surtout pas déclarer virtuel, tant qu'à faire) dans l'accessibilité protégée. Toute tentative d'instanciation de la classe par elle même se soldera par une erreur au motif que le constructeur (le destructeur) est protégé dans ce contexte. Mais l'instanciation des classes dérivées sera autorisée car... les fonctions membres de la classe dérivées (dont le constructeur et le destructeur) ont parfaitement le droit d'accéder aux éléments protégés de leur classe de base (et de toutes leurs classes parentes pour lesquelles il y a eu recours à l'héritage public )

    Enfin, bref, au final, une classe abstraite template prendra tout simplement la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <typename T>
    class Abstract{
    public:
        /* les fonctions publiques spécifiques */
    protected:
        Abstract(/* paramètres éventuels */ ){/* utilisation éventuelles des paramètres (par les différents biais possibles */}
        ~Abstract(){}
        /* autres membres et fonctions protégés*/
    private:
        /* les membres et fonction privés */
    };
    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

  5. #5
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Notes juste Flob, que je n'aurais pas utilisé le principe de la fonction virtuelle pure pour rendre la classe A<U> abstraite... Le compilateur a généralement énormément de mal à se rendre compte qu'une fonction déclarée comme virtuelle pure dans une classe template a bel et bien été définie dans les classes dérivée (ce qui devrait avoir pour résultat de rendre la classe dérivée instanciable )
    Je comprends pas a quoi tu penses.

    A vrai dire, comme le rôle des template est de générer du code spécifique à chaque spécialisation du paramètre template à la compilation, je ne sais même jamais si la norme autorise l'idée d'une fonction virtuelle dans une classe template destinée à servir de classe de base dans un hiérarchie
    Quel serait le probleme des virtuelles dans les templates de classes? (j'aime pas "classe template" qui laisse penser que c'est une classe, "class template" en anglais est un template -- la norme a joue un temps sur la difference entre "class template" et "template class", ce dernier etant bien une classe puisque ca designait ce qu'on appelle une instanciation).

    Chaque instanciation d'un template de classe est bien une classe et peut avoir des virtuelles.

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Je comprends pas a quoi tu penses.
    Au problème qu'il pourrait y avoir avec une fonction virtuelle qui est (implicitement) déclarée inline, avec tout ce que cela comporte d'incompatibilité entre l'inlining et l'appel à une Vtbl.

    Je sais avoir déjà posé ce genre de question et n'avoir jamais "percuté" sur la réponse. Et il me semble avoir rencontré certaines situations dans lesquelles le compilateur se plaignait qu'un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
    template <typename T>
    class Base{
        public:
            virtual void foo()  = 0; //fonction virutelle pure --> classe abstraite
    };
     
    class Derivee : public Base<nimportequeltype>{
        virtual void foo() ; // ce n'est plus une fonction virtuelle ici
    };
    avait pour résultat de laisser une fonction virtuelle pure et de rendre la classe Derivee abstraite. Je n'ai plus de code sous la main à ce sujet, il n'est pas impossible que ce soit, entre autres à cause d'un éventuel argument qui devrait être de type T dans Base, mais je n'ai absolument aucune certitude (je ferai mes recherches )
    Quel serait le probleme des virtuelles dans les templates de classes? (j'aime pas "classe template" qui laisse penser que c'est une classe, "class template" en anglais est un template -- la norme a joue un temps sur la difference entre "class template" et "template class", ce dernier etant bien une classe puisque ca designait ce qu'on appelle une instanciation).
    Justement, j'en vois deux que je viens de citer (et je parle bel et bien d'une situation telle que présentée par mon code, non d'une situation dans laquelle ce serait la classe template qui hérite d'une classe "classique" ):
    • l'incompatibilité entre la déclaration inline qui est implicite pour toute fonction définie dans la définition de la structure et l'utilisation (la création) d'une table de fonctions virtuelles et
    • certaines difficultés que le compilateur pourrait avoir à constater que l'implémentation de la fonction virtuelle dans la classe dérivée correspond bel et bien à l'implémentation de la fonction que l'on a explicitement indiquée comme étant virtuelle pure dans la classe de base (qui serait une tempalte class ).


    Quoi qu'il en soit, comme il existe des solutions qui nous permettent d'éviter qu'une classe (qu'il s'agisse de template class ou non) soit instanciable sans passer par une classe dérivée sans avoir à sortir la virtualité et les fonctions virtuelles pures, en déclarant simplement le destructeur dans l'accessibilité protégée (cela suffit généralement), à défaut de savoir si le PO a effectivement besoin d'une fonction virtuelle pure (et ca, seule une analyse correcte de ses besoins pourra nous le dire), je crois que je préférerai partir sur un destructeur protégé que sur une fonction virutelle pure (quelle que soit cette fonction) "par défaut"

    Après tout, la virutalité du destructeur n'est pas du tout obligatoire pour une classe de base si on ne se trouve pas dans une situation dans laquelle il faut détruire un objet du type dérivé "passant pour être" du type de base... On a donc tout à gagner à rendre la création (et ici surtout la destruction) du type de base sans passer par le type dérivé impossible
    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

  7. #7
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Au problème qu'il pourrait y avoir avec une fonction virtuelle qui est (implicitement) déclarée inline, avec tout ce que cela comporte d'incompatibilité entre l'inlining et l'appel à une Vtbl.
    Ca n'a en effet guere de sens de mettre une fonction virtuelle inline (c'est une remarque que je fais regulierement en revue de code), mais ca n'a jamais gene les compilateurs (je n'aurais pas l'occasion de faire la remarque sinon), en particulier avec les templates qui doivent de toute maniere deja gerer les problemes de duplications (pour les statiques, pour pouvoir comparer les pointeurs de fonction). (En absence de template, j'ai deja vu des problemes avec des classes qui ne resultaient pas d'instanciation de templates et avaient toutes leur virtuelles inline; ca doit faire 10 ans que je n'en ai plus vu, je ne sais pas si c'est parce que les compilateurs ont abandonne l'heuristique de mettre la vtbl dans l'unite qui defini la premiere fonction virtuelle ou parce que le cas ne s'est plus presente parce qu'il a peu de sens.)

    (je ferai mes recherches )
    Le cas exact m'interesse.

    Justement, j'en vois deux que je viens de citer (et je parle bel et bien d'une situation telle que présentée par mon code, non d'une situation dans laquelle ce serait la classe template qui hérite d'une classe "classique" ):
    • l'incompatibilité entre la déclaration inline qui est implicite pour toute fonction définie dans la définition de la structure et l'utilisation (la création) d'une table de fonctions virtuelles et
    Voir ci-dessus, il n'y a pas d'incompatibilite formelle. Ca a pose des problemes avec un heuristique d'implementation si toutes les virtuelles etaient inline, mais l'heuristique n'a ma connaissance n'a jamais ete utilisee pour les templates (qui n'ont pas besoin de cette heuristique avec le mecanisme d'instanciation habituel).

    • certaines difficultés que le compilateur pourrait avoir à constater que l'implémentation de la fonction virtuelle dans la classe dérivée correspond bel et bien à l'implémentation de la fonction que l'on a explicitement indiquée comme étant virtuelle pure dans la classe de base (qui serait une tempalte class ).
    Je ne vois vraiment pas quelle difficulte il y a. (ca n'a jamais exclus les bugs, mais les problemes dont tu as peur me semblent etre de cette nature).

Discussions similaires

  1. Spécialisation de template particulière
    Par Flo. dans le forum Langage
    Réponses: 4
    Dernier message: 25/03/2009, 22h18
  2. Spécialisation de template parametre avec Enum
    Par 3DArchi dans le forum Langage
    Réponses: 4
    Dernier message: 24/09/2008, 15h21
  3. Spécialisation de template
    Par bobyjoe dans le forum Langage
    Réponses: 18
    Dernier message: 13/12/2007, 21h52
  4. Réponses: 8
    Dernier message: 24/04/2007, 22h09
  5. Réponses: 7
    Dernier message: 01/01/2006, 03h28

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