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 :

Template et héritage privé.


Sujet :

Langage C++

  1. #1
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut Template et héritage privé.
    Bonjour,
    Soit une classe générique Type qui hérite en private d'un de ses paramètres.
    Soit une classe Derive dérivant de cette classe générique Type instanciée avec une troisième classe UneBase.
    J'ai des erreurs lorsque j'essaie d'accéder à la classe générique Type depuis la classe Derive comme quoi la classe UneBase est inaccessible car privée. Or, je n'accède pas à cette classe privée.
    Exemple :
    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
    25
    26
    27
    28
    29
    30
    31
    32
    #include <iostream>
     
    template<class TBase>
    struct Type : private TBase
    {
       Type():TBase()
       {
          std::cout<<"Type<>"<<std::endl;
       }
    };
     
    struct UneBase
    {
       UneBase()
       {
          std::cout<<"UneBase"<<std::endl;
       }
    };
     
    struct Derive : public Type<UneBase>
    {
       Derive():Type<UneBase>()
       {
          std::cout<<"Derive"<<std::endl;
       }
    };
     
    int main()
    {
       Derive d;
       return 0;
    }
    Sur Derive():Type<UneBase>(), j'obtient :
    Citation Envoyé par gcc/Mingw
    In constructor 'Derive:: Derive()'
    error: 'struct UneBase' is inaccessible
    error: within this context
    Citation Envoyé par VisualExpress
    error C2247: 'UneBase' non accessible, car 'Type<TBase>' utilise 'private' pour hériter de 'UneBase'
    with
    [
    TBase=UneBase
    ]
    Bon, je me dis que je vais changer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Derive():Type<UneBase>()
    en :
    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
    25
    26
    27
    28
    29
    30
    31
    32
    #include <iostream>
     
    template<class TBase>
    struct Type : private TBase
    {
       Type():TBase()
       {
          std::cout<<"Type<>"<<std::endl;
       }
    };
     
    struct UneBase
    {
       UneBase()
       {
          std::cout<<"UneBase"<<std::endl;
       }
    };
     
    struct Derive : public Type<UneBase>
    {
       Derive():Type()
       {
          std::cout<<"Derive"<<std::endl;
       }
    };
     
    int main()
    {
       Derive d;
       return 0;
    }
    Et là, nouvelle erreur :
    Citation Envoyé par gcc/MinGW
    In constructor 'Derive:: Derive()':
    error: class 'Derive' does not have any field named 'Type'
    En revanche Visual accèpte.
    Mais je dois pouvoir compiler avec les 2 compilateurs.

    J'avoue que je ne vois ni d'où vient le premier problème ni le second.
    Mais surtout, je ne vois pas comment résoudre la chose.

  2. #2
    screetch
    Invité(e)
    Par défaut
    bizarre ca

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    template< typename Base >
    struct Type : private Base
    {
       Type():Base()
       {
          std::cout<<"Type<>"<<std::endl;
       }
    };
    ca ne marche pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    template< int i >
    struct Type : private UneBase
    {
       Type():UneBase()
       {
          std::cout<<"Type<>"<<std::endl;
       }
    };
    ca marche

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    template< typename Base >
    struct Type : private Base
    {
       Type()
       {
          std::cout<<"Type<>"<<std::endl;
       }
    };
    ca marche aussi (je n'ai pas appelé de constructeur explicite; je laisse le compilo faire l'appel au constructeur implicitement)

    g++ 4.3 sous debian

    en héritage protégé ca marche, je dirai que c'est le plus facile pour toi...

    pour le second problème il me semble que c'est GCC qui a raison et Visual est trop laxiste

  3. #3
    screetch
    Invité(e)
    Par défaut
    trouvé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct Derive : public Type<UneBase>
    {
       Derive():Type< ::UneBase>()
       {
          std::cout<<"Derive"<<std::endl;
       }
    };
    le probleme vient du fait quel orsqu'on dérive de UneBase en privé, on injecte ce nom dans l'espace de noms connus (il va se servir de l'héritage pour trouver UneBase) mais l'héritage etant privé on a pas le droit d'y acceder
    mais si tu lui donnes le nom complet, la d'un seul coup il devient moins con et il trouve la vraie déclaration

  4. #4
    screetch
    Invité(e)
    Par défaut
    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
    template< typename Base >
    struct Type : private Base
    {
        typedef Type<Base> Parent;
       Type():Base()
       {
          std::cout<<"Type<>"<<std::endl;
       }
    };
     
    struct Derive : public Type<UneBase>
    {
       Derive() : Parent()
       {
          std::cout<<"Derive"<<std::endl;
       }
    };
    marche aussi du coup, mais c'est pas glop

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut

    J'avais bien senti qu'il allait chercher le nom dans l'héritage mais j'ai pas eu l'idée de donner le nom complet. Ca marche impec !
    J'avais essayé le typedef ... mais à l'intérieur de la classe dérivée ce qui ne changeait pas le problème.
    Je préfère la solution consistant à indiquer le nom complet car elle montre bien et la cause du problème et sa solution.
    Attention bien sur à l'espace entre '<' et '::' sinon
    <:' is an alternate spelling for '['. Insert whitespace between '<' and '::'
    C'est amusant car je croyais que ce genre d'erreur (<::) était gérée en C++0x et gcc avec -std=c++0x me sort quand même l'erreur.



    [EDIT] : l'exemple était simplifié. En fait je ne peux me contenter de laisser le compilateur appeler le constructeur implicitement car je veux en appeler un particulier avec des arguments y tout. Quand à l'héritage protégé, ça signifie pas la même chose et ça correspond pas à ce que je voulais faire...

  6. #6
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    [EDIT] : l'exemple était simplifié. En fait je ne peux me contenter de laisser le compilateur appeler le constructeur implicitement car je veux en appeler un particulier avec des arguments y tout.
    Tu ne peux pas le faire là ?!
    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    #include <string>
    #include <iostream>
     
    template<class TBase>
    struct Type : private TBase
    {
      Type():TBase()
      {
        std::cout<<"Type<>"<<std::endl;
      }
      Type(const std::string& s) : TBase(s)
      {
        std::cout << "Type<>(const std::string&)" << std::endl;
      }
    };
     
    struct UneBase
    {
      UneBase(const std::string& s)
      {
        std::cout << s << std::endl;
      }
    };
     
    struct Derive : public Type<UneBase>
    {
      Derive() : Type< ::UneBase >("C++")
      {
        std::cout<<"Derive"<<std::endl;
      }
    };
     
    int main()
    {
      Derive d;
      return 0;
    }
    /* $ ./archi
    C++
    Type<>(const std::string&)
    Derive
    */

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Alp Voir le message
    Tu ne peux pas le faire là ?!
    Sisi. Avec le nom complet, il n'y a plus de problème (ce qui se comprend).

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

Discussions similaires

  1. Template et héritage
    Par rooger dans le forum Langage
    Réponses: 5
    Dernier message: 22/07/2008, 13h48
  2. Foncteur, classes templates et héritage
    Par Floréal dans le forum C++
    Réponses: 8
    Dernier message: 17/06/2007, 21h56
  3. Template ou héritage
    Par bolhrak dans le forum Langage
    Réponses: 6
    Dernier message: 22/12/2006, 11h22
  4. patron, templates et héritages!
    Par kleenex dans le forum C++
    Réponses: 4
    Dernier message: 05/06/2006, 22h57
  5. [héritage privé] appel du constructeur de base
    Par PINGOUIN_GEANT dans le forum C++
    Réponses: 4
    Dernier message: 19/10/2004, 14h05

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