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 :

Heritage-Spécialisation d'un template


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur
    Inscrit en
    Décembre 2006
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 96
    Par défaut Heritage-Spécialisation d'un template
    Salut à tous

    J'ai un petit souci avec des templates que je voudrais hériter tout en spécialisant le type. Je vais essayer d'être clair.

    Pour le contexte je suis en train de développer un petit accordeur numérique sous forme de AudioUnit (format de plugin audio Apple), et pour la vue (autrement dit la Gui), je vais mettre en place deux indicateurs : un qui affiche la note jouée et un autre qui affiche l'écart avec la note exacte (le pitch).

    Ce qu'affichent les indicateurs dépend de données de types différents :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef double Pitch_t;
    typedef	enum {
    	kNote_La = 0,
    	kNote_Sib = 1,
    	...
    	kNote_None = 12
    } NoteID_t;
    J'ai donc créer un template indicateur de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <class T>
    class ViewIndicator
    {
    public:
    	ViewIndicator (...);
    	virtual ~ViewIndicator ();
     
    	void getData();       // va chercher les données dans la partie audio du plugin
    	virtual void draw();
    protected:
    	T mData;
    };
    et des classes héritées-spécialisées de la manière suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class PitchIndicator : public ViewIndicator<Pitch_t>
    {
    public:
    	PitchIndicator	(...);
    	~PitchIndicator();
     
    	void draw ();
    };
     
    // idem pour NoteIndicator
    Les fonctions draw() des classes héritées appellent d'abord ViewIndicator::draw() pour dessiner l'arrière-plan de l'afficheur puis utilise mData pour afficher ce qu'il faut.

    Là ou ça se gate, c'est dans l'implémentation, notamment l'initialisation par les super-constructeurs : j'ai fais (entre autres) deux essais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    PitchIndicator::PitchIndicator(...)
    	:	ViewIndicator(...)
     
    PitchIndicator::PitchIndicator(...)
    	:	ViewIndicator<Pitch_t>::ViewIndicator(...)
    {}
    Le premier génère une error de compilation :
    error: no matching function for call to 'ViewIndicator<Pitch_t>::ViewIndicator()'
    error: class 'PitchIndicator' does not have any field named 'ViewIndicator'

    Le second compile mais génère des erreurs de linking comme quoi il lui manque ViewIndicateur<double> et ViewIndicateur<NoteID_t>


    Je suis prêt à envisager d'autres conceptions, seulement j'aimerais garder si possible le mécanisme d'héritage qui me permet d'automatiser un certain nombre de choses (d'autant plus que j'ai l'intention d'inclure la classe ViewIndicator dans API, il faudrait donc que les utilisateurs aient le moins possible à écrire, par exemple ne surcharger que la fonction draw()).

    Merci d'avance
    Rémi

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Salut,

    Il faut faire ça je dirais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    PitchIndicator::PitchIndicator(...)
    	:	ViewIndicator<Pitch_t>(...)
    {}
    MAT.

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur
    Inscrit en
    Décembre 2006
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 96
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Salut,

    Il faut faire ça je dirais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    PitchIndicator::PitchIndicator(...)
    	:	ViewIndicator<Pitch_t>(...)
    {}
    MAT.
    Merci c'est super, ça marche

    J'ai quand même une dernière question : dans ViewIndicator, j'ai défini une fonction (publique) à laquelle j'aimerais accéder à travers une instance d'un PitchIndicator :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    PitchIndicator* monPitch;
    ...
    (ViewIndicator<Pitch_t>*) monPitch->maFonction();
    là, gcc me dit : error: 'ViewIndicator<Pitch_t>' is not an accessible base of 'PitchIndicator'

    pourtant j'ai bien déclaré
    class PitchIndicator : public ViewIndicator<Pitch_t>

    Si je ne voulais pas me prendre la tête, j'aurais pu surcharger la fonction dans PitchIndicator, mais dans l'esprit du programme elle n'a vraiment pas lieu de l'être.

    Quelqu'un à une idée là dessus ?
    Rémi

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    PitchIndicator* monPitch;
    ...
    monPitch->maFonction();
    Devrait fonctionner normalement.

    Par contre là ton transtypage est fait sur le retour de maFonction et non sur monPitch, il faudrait faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    PitchIndicator* monPitch;
    ...
    ((ViewIndicator<Pitch_t>*) monPitch)->maFonction();
    Mais pas besoin a priori.
    C'est super moche les transtypages C-style, si vraiment tu tiens à en faire un il vaut mieux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    PitchIndicator* monPitch;
    ...
    dynamic_cast< ViewIndicator<Pitch_t>* >( monPitch )->maFonction();
    MAT.

  5. #5
    Membre confirmé
    Homme Profil pro
    Ingénieur
    Inscrit en
    Décembre 2006
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 96
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Salut,

    Il faut faire ça je dirais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    PitchIndicator::PitchIndicator(...)
    	:	ViewIndicator<Pitch_t>(...)
    {}
    MAT.
    merci MAT

    En fait, j'ai crié victoire un peu trop vite : ça compile bien mais j'ai les mêmes erreurs de linking que précedemment :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Undefined symbols:
      "ViewIndicator<double>::~ViewIndicator()", referenced from:
          PitchIndicator::~PitchIndicator()in PitchIndicator.o
          PitchIndicator::~PitchIndicator()in PitchIndicator.o
      "ViewIndicator<NoteID_t>::~ViewIndicator()", referenced from:
          NoteIndicator::NoteIndicator( ... )in NoteIndicator.o
          NoteIndicator::~NoteIndicator()in NoteIndicator.o
          NoteIndicator::~NoteIndicator()in NoteIndicator.o
          NoteIndicator::~NoteIndicator()in NoteIndicator.o
          NoteIndicator::~NoteIndicator()in NoteIndicator.o
      "ViewIndicator<double>::draw()", referenced from:
          PitchIndicator::draw()      in PitchIndicator.o
      "ViewIndicator<NoteID_t>::draw()", referenced from:
          NoteIndicator::draw()      in NoteIndicator.o
      "ViewIndicator<double>::ViewIndicator( ... )", referenced from:
          PitchIndicator::PitchIndicator( ... )in PitchIndicator.o
      "ViewIndicator<NoteID_t>::ViewIndicator( ... )", referenced from:
          NoteIndicator::NoteIndicator( ... )in NoteIndicator.o
    Si je les comprend bien, les classe NoteIndicator et PitchIndicator sont incapables d'acceder aux fonctions de leur classe (ou l'éditeur de lien ne les trouve pas). c'est à dire qu'il n'a pas compilé l'implémentation de ViewIndicator<NoteID_t> et ViewIndicator<Pitch_t> ?

    hesitez pas à me demander plus de code au besoin.

  6. #6
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Est-ce que par hasard ton problème ne serait pas exactement le même que celui décrit dans cette entrée de la FAQ ?

    MAT.

  7. #7
    Membre confirmé
    Homme Profil pro
    Ingénieur
    Inscrit en
    Décembre 2006
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 96
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Est-ce que par hasard ton problème ne serait pas exactement le même que celui décrit dans cette entrée de la FAQ ?

    MAT.
    C'est exactement ça.
    Merci beaucoup MAT.

  8. #8
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Citation Envoyé par remitbo Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    typedef	enum {
    	kNote_La = 0,
    	kNote_Sib = 1,
    	...
    	kNote_None = 12
    } NoteID_t;
    En C++, on écrit les enums comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    enum NoteID_t {
    	kNote_La = 0,
    	kNote_Sib = 1,
    	...
    	kNote_None = 12
    };

  9. #9
    Membre confirmé
    Homme Profil pro
    Ingénieur
    Inscrit en
    Décembre 2006
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 96
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    En C++, on écrit les enums comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    enum NoteID_t {
    	kNote_La = 0,
    	kNote_Sib = 1,
    	...
    	kNote_None = 12
    };
    ok je prend note.

  10. #10
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    De plus, si mes souvenirs sont bons, il suffit de spécifier la première valeur de l'enum, et les autres valeurs de l'énumération ajouteront automatiquement 1.

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

Discussions similaires

  1. [Template] spécialisation partielle des template
    Par vikki dans le forum Langage
    Réponses: 9
    Dernier message: 10/11/2008, 16h29
  2. Réponses: 4
    Dernier message: 04/09/2008, 10h58
  3. Spécialisation de classe Template
    Par mister3957 dans le forum Langage
    Réponses: 2
    Dernier message: 21/07/2008, 15h35
  4. Problème de spécialisation de fonction template membre
    Par Davidbrcz dans le forum Langage
    Réponses: 4
    Dernier message: 29/12/2007, 20h01
  5. spécialisation d'un template
    Par meuns26 dans le forum Langage
    Réponses: 6
    Dernier message: 23/08/2007, 14h53

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