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 :

Templates et constructeurs de classe héritées


Sujet :

Langage C++

  1. #1
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut Templates et constructeurs de classe héritées
    Hey,
    J'ai un souci pour une construction en C++11 qui m'embête.

    J'ai une classe template qui hérite de son paramètre template, et elle n'a pas de constructeur par défaut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<typename T>
    class Main : public T
    {
    public:
     // méthodes
    };
    Ca fonctionne très bien pour la majorité de mes classes mère, mais j'ai maintenant besoind 'avoir une classe fille qui a un constructeur qui prend des arguments. Le souci, c'est que je pensais que le constructeur de Main suivrait le prototype de celui de ma classe mère, mais apparemment dans le monde des templates, ce n'est pas le cas.
    J'ai tenté des using, mais comme le nom du constructeur est différent selon la classe fille, ça ne passe pas !

    Des idées ?

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    en principe, tu peux faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<typename T>
    class Main : public T
    {
    public:
        Main() :T("un argument") {}
    };
    Théoriquement, il existe les "inherited constructors", mais je ne les ai pas encore utilisé

  3. #3
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    En principe, mais en fait non. Parce que T peut avoir différentes signatures, selon son type. Par défait, ça sera T(), donc tout passe, mais dans le cas qui me préoccupe, c'est T(double, double).

    J'aimerait bien utiliser les constructeurs dérivés, le souci, c'estq ue faire un using T::T va ramener la méthode "T" de ma classe parente, pas son constructeur :/

  4. #4
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Bon... J'ai constaté que mon Visual Studio n'avait pas les inherited constructors...

  5. #5
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Tu peux avoir recours à la spécialisation, si la taille de la classe est modeste, et qu'il y a peu de cas à traiter.

    Tu peux avoir recours à une classe de base, éventuellement template de T, pour ne pas tout redéfinir dans la spécialisation.

    Si tu sais que tu utiliseras ta template uniquement avec certaines classes, le problème est bien réduit.

    Si tu sais que c'est "(double, double)", ma proposition est valable:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<typename T>
    class Main : public T
    {
    public:
        Main(double a, double b) :T(a, b) {}
    };

  6. #6
    Membre émérite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Par défaut
    Bonjour,

    Peut-être avec des templates variadiques :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template <typename T>
    class Main : public T {
      public:
        template <typename... Args>
          Main(Args&&... args):T(std::forward(args)...) {}
    };

  7. #7
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    je n'y pense pas assez. ca doit marcher

  8. #8
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par the Hound Voir le message
    Bonjour,

    Peut-être avec des templates variadiques :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template <typename T>
    class Main : public T {
      public:
        template <typename... Args>
          Main(Args&&... args):T(std::forward(args)...) {}
    };
    Ca semble intéressant, je vais voir si mes compilateurs supportent ça (certains sont très vieux )
    Merci !

    leternel > sans doute, mais la classe est tout de même un peu complexe, et elle était là pour abstraire toute la partie setup d'un traitement. Le traitement est identique, mais tout de même assez complexe.

  9. #9
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Citation Envoyé par the Hound Voir le message
    Bonjour,

    Peut-être avec des templates variadiques :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template <typename T>
    class Main : public T {
      public:
        template <typename... Args>
          Main(Args&&... args):T(std::forward(args)...) {}
    };
    Quitte à faire ça autant faire de la composition plutôt que de l'héritage en passant le T en paramètre du constructeur (en plus ça passera sur de vieux compilateurs).

  10. #10
    Membre émérite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Par défaut
    Tout dépend de ce qui est recherché ici, si on veut que Main fournisse la même "interface" que la classe qu'elle reçoit en paramètre template, c'est une solution possible. Bien sûr dans des cas concrets on va rarement recourir à ce genre de design.

  11. #11
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par Trademark Voir le message
    Quitte à faire ça autant faire de la composition plutôt que de l'héritage en passant le T en paramètre du constructeur (en plus ça passera sur de vieux compilateurs).
    Je me suis posé la question, mais pour le moment, je reste avec de l'héritage, mais c'est clair qu'il est possible que ça change. Le souci est que la composition va cacher l'objet qui a sa propre interface qui doit être accessible. Bref, je verrai pour la release officielle de la 1.0 !

  12. #12
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    en composant, tu peux proposer, par exemple, les operateurs * et ->, pour inférer vers la classe composée. Comme le fait un smart pointer ou un optional

  13. #13
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    :/ oui et non. La classe composée doit utiliser des outils de la classe de base (typiquement des fréquences d'échantillonnage) pour calculer ses coefficients. Et au-dessus de ça, il y a la classe qui fait le calcul en nécessitant l'interface de la classe de base (car polymorphisme dynamique) et la partie "amovible" de calcul des coeffs. C'est pas instantané de séparer les deux.
    En fin de compte, j'ai dû modifier le constructeur pour qu'il prenne en compte un autre paramètre et je suis passé par une méthode protégée pour setter les paramètres, le tout dans des méthodes builder (statiques).

  14. #14
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    l'inverse ne serait-il pas possible? Je veux dire, faire hériter ta classe Main de ta nouvelle classe, plutôt que l'inverse? J'ai vu ça récemment dans la lib OpenSceneGraph, ici.

    Juste pour la culture générale, ce pattern s'appelle le CRTP.

  15. #15
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    C'est déjà ce que j'utilise en réalité (la classe IIRFilter dans https://github.com/mbrucher/AudioTK)

Discussions similaires

  1. class template et constructeur
    Par Gorgo13 dans le forum C++/CLI
    Réponses: 3
    Dernier message: 21/11/2012, 11h52
  2. Réponses: 10
    Dernier message: 04/04/2012, 21h30
  3. Réponses: 4
    Dernier message: 02/08/2010, 15h13
  4. classe template pb constructeur
    Par ouinih dans le forum Langage
    Réponses: 6
    Dernier message: 16/08/2007, 18h02
  5. Réponses: 2
    Dernier message: 04/12/2005, 21h10

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