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 :

template et héritage de containeur


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2005
    Messages : 168
    Points : 85
    Points
    85
    Par défaut template et héritage de containeur
    Bonjour,

    J'ai un problème que je ne comprends pas. J'ai créé une classe héritant de QList :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    template<class T>
    class A: public QList<<T> > {
    ...
     
    int f() {
        return size();
    }
    }
    et j'obtiens l'erreur suivante :

    there are no arguments to ‘size’ that depend on a template parameter, so a declaration of ‘size’ must be available

    Quelqu'un pourrait-il m'aider ? Est-ce que j'ai zappé quelque chose d'important dans la déclaration de ma classe ?

  2. #2
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2011
    Messages : 13
    Points : 33
    Points
    33
    Par défaut
    Quand tu hérites d'une base template tu dois préfixer les appels des fonctions de la base par son type.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int f() {
        return QList<T>::size();
    }
    Soit dis en passant j'aurais plutôt tendance a faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<class T>
    class A: public QList<T> 
    {
    public:
        using QList<T>::size;
    }
    Ceci bien sur dans la mesure ou tu n'a pas besoin de changer le comportement de la fonction size de la classe de base.
    Attention également, dans le cas de la STL et potentiellement de ton QList, le destructeur n'est pas virtuel.

  3. #3
    Membre expérimenté 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
    Points : 1 396
    Points
    1 396
    Par défaut
    Généralement c'est une très mauvaise idée d'hériter d'un container. Il faut que tu envisages la composition ! Notamment parce que aucunes méthodes n'est virtuelles.

    Sujet déjà abordé ici : http://www.developpez.net/forums/d25...eriter-vector/

    et la : http://www.developpez.net/forums/d77...r-classes-stl/

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Et la FAQ : Pourquoi et quand faut-il créer un destructeur virtuel ?
    Et je vais insister plus que les 2 autres intervenants : tu dois pas faire ça

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2005
    Messages : 168
    Points : 85
    Points
    85
    Par défaut
    Bon ben je vais révisé ma copie

    Merci pour vos réponses !

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2005
    Messages : 168
    Points : 85
    Points
    85
    Par défaut
    @Gymble : les <> sont un oubli de ma part, j'aurais dû les effacer.

    Sinon, je vais passer par la composition même si cette solution ne m'enchante pas trop puisque cela demande d'écrire du code supplémentaire.

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,
    Citation Envoyé par Gébix Voir le message
    @Gymble : les <> sont un oubli de ma part, j'aurais dû les effacer.

    Sinon, je vais passer par la composition même si cette solution ne m'enchante pas trop puisque cela demande d'écrire du code supplémentaire.
    Heuu... sincèrement... :
    1. Le code supplémentaire à écrire tient en trois ou quatre fonctions et éventuellement deux typedef
    2. Le code supplémentaire à écrire tient, en gros, à simplement appeler les fonctions de QList
    ce sera sans doute du genre de :
    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
    19
    20
    21
    22
    23
    24
     
    template <typename T>
    class A
    {
            typedef QList<T> list;
        public:
            typedef typename list::iterator iterator;
            typedef typename list::const_iterator const_iterator;
            A & operator << (T const & toadd)
           {
               list_<< toadd;
               return *this;
           }
           iterator begin() {return list_.begin();}
           iterator end() {return list_.end();}
           const_iterator begin() const {return list_.begin();}
           const_iterator end() const  {return list_.end();}
           bool isEmpty() const{retun list_.isEmpty();}
           size_t size() const{return list_.size();}
           T & operator [](size_t index){return list_[index];}
           T const & operator [](size_t index) const {return list_[index];}
        private:
            list_ list_;
    };
    (ca m'a pris royalement deux minutes trente à écrire ce code "from scratch" ... meme si j'écris peut etre très vite )

    Ce n'est peut etre pas vraiment gai, mais bon, ce n'est pas la mort non plus

    Sans oublier que tu peux parfaitement envisager l'héritage privé et les directives using

    Mais bon, deux questions demeurent sans réponse :

    Etant donné que A est une classe template, tu dis, d'office, adieux à la virtualité (template et virtualité, dans le cas présent, ne font pas bon ménage)...

    Que Prévois tu donc de faire avec cette classe A qui aurait pu justifier que tu hérite de QList et que tu n'aurais pas pu faire avec ... QList

    N'aurais tu pas pu te contenter de créer des fonctions libres qui auraient eu un comportement identique

    Finalement, avec des fonctions libres template, tu aurais sans dout très bien pu arriver au même résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template <typename T>
    void foo( QList<T> const & laliste /* , autres paramètres éventuels*/ )
    {
        /* utilisation de laliste */
    }
    Et cela ne t'aurait meme pas empêché de surcharger la fonction pour une QList contenant des objets d'un type particulier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void foo(QList<MonTypeParticulier /* * */ > laliste /* ,autres paramètres éventuels*/ )
    {
        /* utilisation de laliste, adapté spécifiquement à  MonTypeParticulier  (*)*/
    }
    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

  8. #8
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    D'un autre côté, l'erreur de Gébix est compréhensible : on lui dit qu'il ne faut pas hériter de QList, mais si on regarde la doc de QList, on voit que plusieurs conteneurs de Qt dérivent de QList

    On l'a déjà dit, mais c'est bien de la rappeler : Qt n'est pas un exemple à suivre en terme de qualité du code C++

  9. #9
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    D'un autre côté, l'erreur de Gébix est compréhensible : on lui dit qu'il ne faut pas hériter de QList, mais si on regarde la doc de QList, on voit que plusieurs conteneurs de Qt dérivent de QList

    On l'a déjà dit, mais c'est bien de la rappeler : Qt n'est pas un exemple à suivre en terme de qualité du code C++
    En outre, je viens de "percuter" sur le fait que l'héritage d'une classe template avec une classe template ne pose pas les mêmes problèmes que l'héritage d'une classe non template avec une classe template
    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

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2005
    Messages : 168
    Points : 85
    Points
    85
    Par défaut
    @koala01 : faut que je reréfléchisse à comment je recoder mon truc. Pourrais-tu développez ton dernier poste car je ne vois quelle est la différence et cela m'intéresse.

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

Discussions similaires

  1. Template et héritage
    Par Ulmo dans le forum Langage
    Réponses: 16
    Dernier message: 08/03/2009, 23h41
  2. Template et héritage
    Par rooger dans le forum Langage
    Réponses: 5
    Dernier message: 22/07/2008, 13h48
  3. Foncteur, classes templates et héritage
    Par Floréal dans le forum C++
    Réponses: 8
    Dernier message: 17/06/2007, 21h56
  4. Template ou héritage
    Par bolhrak dans le forum Langage
    Réponses: 6
    Dernier message: 22/12/2006, 11h22
  5. patron, templates et héritages!
    Par kleenex dans le forum C++
    Réponses: 4
    Dernier message: 05/06/2006, 22h57

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