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 :

Héritage de template, problème d'accès aux membres protected


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut Héritage de template, problème d'accès aux membres protected
    Bonsoir,

    J'ai un petit problème avec une architecture à base de template.
    On dirait que je ne peut pas accéder aux membres protected, d'une classe de base dans une classe dérivée.

    J'ai grandement simplifié le code pour en arriver là:
    Code main.cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include <cstdlib>
    #include "B.h"
     
    int main(int argc, char * argv[])
    {
    	B<int> b;
    	return EXIT_SUCCESS;
    }

    Code A.h : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #ifndef _A_H
    #define _A_H
     
    template<typename T>
    class A
    {
    public:
    	virtual ~A();
    protected:
    	T var;
    };
     
    #include "A.tpp"
     
    #endif

    Code A.tpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    template<typename T>
    A<T>::~A()
    {}

    Code B.h : 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
    #ifndef _B_H
    #define _B_H
     
    #include "A.h"
     
    template <typename T>
    class B : public A<T>
    {
    public:
    	B();
    	virtual ~B();
    };
     
    #include "B.tpp"
     
    #endif

    Code B.tpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template<typename T>
    B<T>::B()
    {
    	var = 0; //Problème ici
    }
    
    template<typename T>
    B<T>::~B()
    {
    }

    J'utilise g++ 4.1.2 et j'ai ce message d'erreur:
    g++ -c -Wall -Werror -pedantic -pedantic-errors -O3 -std=c++98 main.cpp -o main.o
    B.tpp: In constructor ‘B<T>::B()’:
    B.tpp:4: error: ‘var’ was not declared in this scope
    make: *** [main.o] Erreur 1

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Essaye avec this->var, je crois que c'est nécessaire avec les classes templates (au moins avec gcc).

  3. #3
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Merci .
    Effectivement ça fonctionne, c'est pas dans la norme ça?

    Ça m'amène à une autre question, existe-t-il un meilleur compilateur, multiplateforme et libre que g++?

  4. #4
    Membre expérimenté
    Avatar de David Fleury
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 253
    Par défaut
    Citation Envoyé par MatRem
    Merci .
    Effectivement ça fonctionne, c'est pas dans la norme ça?
    Je crois que oui.
    Vandervoode/Josuttis expliquent pourquoi dans leur bouquin "C++ templates" (9.4.2)

  5. #5
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Ha ok, très bien. Laurent avait l'air de dire que c'était une spécificité de g++.
    J'ai honte de ne plus avoir eu confiance en g++

    Est ce que quelqu'un connaît l'intérêt de ce point? (je ne possède malheureusement pas l'ouvrage que tu sites).

    Sinon je vais regarder dans le Stroustrup s'il en fait mention.

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Par défaut
    On trouve aussi une explication sur le site de gcc. L'idée est que une spécialisation de A peut être déclarée après la déclaration de B, être utilisée par B et ne pas déclarer ta variable. Le compilo ne regarde donc pas dans la classe de base, mais dans le namespace englobant.

  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 MatRem
    Est ce que quelqu'un connaît l'intérêt de ce point? (je ne possède malheureusement pas l'ouvrage que tu sites).
    Le point en question est la recherche des noms en deux phases et est plus general que l'heritage de template.

    Il permet d'avoir une meilleure predictabilite (seuls les noms dépendant explicitement d'un paramètre template en dépendent et ils en dépendent toujours, quelle que soit la valeur du parametre), eviter des cas de comportements indefinis (sans la recherche des noms en deux phases, on peut arriver facilement a des cas ou pour une instantiation donnee, un nom qui n'est pas dependant -- et donc cherche uniquement dans le contexte de la definition du template -- est resolu de maniere differente dans les differents contextes d'instantiation) et permettre la detection d'erreur pour tout ce qui ne depend pas des parametres template quand on voit la definition plutot qu'attendre une instantiation.

  8. #8
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Citation Envoyé par Laurent Gomila
    Essaye avec this->var, je crois que c'est nécessaire avec les classes templates (au moins avec gcc).
    Petite suggestion de ma part:
    C'est plus pratique de déclarer une bonne fois pour toutes la variable dans la classe dérivée avec 'using' qui est là popur ça, plutôt que d'utiliser le pointeur 'this' à chaque utilisation.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template <typename T>
    class B : public A<T>
    {
      public:
         typedef A<T> base;
         using base::var;
     
    ...
    };

  9. #9
    Membre expérimenté
    Avatar de David Fleury
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 253
    Par défaut
    Citation Envoyé par Charlemagne
    Petite suggestion de ma part:
    C'est plus pratique de déclarer une bonne fois pour toutes la variable dans la classe dérivée avec 'using' qui est là popur ça, plutôt que d'utiliser le pointeur 'this' à chaque utilisation.
    Dans le livre que j'ai cité, il donne trois variations pour éviter les problèmes de template et name lookup.
    Le using dont tu parles est la deuxième qui (si mes souvenirs sont bons) à le désavantage de désactiver la "virtualité".
    Il y a une troisème variation que je ne me rappelle pas

  10. #10
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Merci pour toutes ces précisions . On dirait qu'on rentre dans le "compliqué" du c++ là. Il va falloir que je me trouve un bouquin spécial template.

    pour koala: en effet j'avais un peu trop simplifié mon exemple, en fait var est initialisé avec un paramètre de type T du constructeur.

  11. #11
    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 MatRem
    Merci pour toutes ces précisions . On dirait qu'on rentre dans le "compliqué" du c++ là. Il va falloir que je me trouve un bouquin spécial template.
    Je conseille fortement celui de Josuttis et van de Voorde.

  12. #12
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Citation Envoyé par Hylvenir
    Dans le livre que j'ai cité, il donne trois variations pour éviter les problèmes de template et name lookup.
    Le using dont tu parles est la deuxième qui (si mes souvenirs sont bons) à le désavantage de désactiver la "virtualité".
    Il y a une troisème variation que je ne me rappelle pas
    Je comprends pas bien ce que tu entends par "désactiver la virtualité"? un petit exemple peut-être? en tout cas ça ne peut détruire la virtualité que pour les fonctions, ici c'est une variable.

    Si tu retrouves la 3ème possibilité, je suis curieux.

  13. #13
    Membre expérimenté
    Avatar de David Fleury
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 253
    Par défaut
    Alors, voilà à ce que j'ai compris
    variation 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template<typename T>
    struct Derived : public Base<T> {
     void fct() { this->basefield_ = 0; }
    };
    // le this permet de faire la résolution de nom à l'instantiation du template
    variation 2:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    template<typename T>
    struct Derived : public Base<T> {
     void fct() { Base<T>::basefield_ = 0; }
    };
    // il semble que le nom qualifié désactive les appels virtuels (l'aide des gurus
    // est la bienvenue sur ce point ;)
    variation 3 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    template<typename T>
    struct Derived : public Base<T> {
     using Base<T>::basefield_;
     void fct() { basefield_ = 0; }
    };
    // il peut y avoir des soucis pour qualifier comme il faut en cas d'héritage
    // multiples
    "C++ Templates" - The complete guide.
    Vandevoorde/Josuttis.
    un "must-have" pour essayer de comprendre les templates.

Discussions similaires

  1. Réponses: 4
    Dernier message: 04/09/2008, 10h58
  2. Réponses: 16
    Dernier message: 07/02/2006, 14h19
  3. [Applet] problèmes d'accès aux images
    Par wwave dans le forum Interfaces Graphiques en Java
    Réponses: 18
    Dernier message: 16/09/2005, 14h42
  4. Heritage accès aux membres de bases
    Par MAGNUM_HEAD dans le forum C++
    Réponses: 1
    Dernier message: 16/11/2004, 16h41
  5. [TOMCAT] JSP problème d'accès aux méthodes d'une classes
    Par gunnm dans le forum Tomcat et TomEE
    Réponses: 3
    Dernier message: 22/05/2004, 14h02

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