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 :

sous classes et friend?


Sujet :

Langage C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 69
    Points : 62
    Points
    62
    Par défaut [Résolu]sous classes et friend?
    Bonjour à tous,

    J'ai remarqué que dans VS2008, une sous-classe a un accès direct aux attributs de la sur-classe.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    struct B
    {
    struct SousClasse
    {
       void doMeBaby(B* b){b->i = 1;}
    };
    private : 
     int i;
    }; // ceci fonctionne sous VS2008
    Quelqu'un peut-il me confirmer ou infirmer que dans le standard C++ (que je ne trouve pas grrr ou alors à 18$) la structure SousClasse ne devrait pas avoir accès à 'i'?

    Selon la réponse j'aurais des questions + avancées.

    ElPedro

  2. #2
    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
    Salut,
    La Norme (qui est payante et n'existe pas en gratuit) dit bien que :
    11.8 Nested classes
    1 The members of a nested class have no special access to members of an enclosing class, nor to classes or functions that have granted friendship to an enclosing class; the usual access rules (clause 11) shall be obeyed. The members of an enclosing class have no special access to members of a nested class; the usual access rules (clause 11) shall be obeyed.
    [Example:
    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
    class E {
       int x;
       class B { };
       class I {
          B b; // error: E::B is private (1)
          int y;
          void f(E* p, int i)
          {
             p->x = i; // error: E::x is private (2)
          }
       };
       int g(I* p)
       {
          return p->y; // error: I::y is private (3)
       }
    };
    —end example]
    En pratique, MinGW/gcc laisse passé (1) et (2) mais râle sur (3). Idem pour visual.
    Il y a peut être une subtilité quelque part ?

  3. #3
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Il y a peut être une subtilité quelque part ?
    A mon avis, ils (les compilateurs) considèrent simplement les membres des classes membres comme des membres et les fonctions membres des classes membres comme des fonctions membres. Ce qui justifie (1) et (2). En un sens, c'est logique puisqu'une classe a toujours accès aux variables de son bloc/fichier.

    Par contre aucune règle ne permettant d'accéder aux membres privés de ses membres, (3) n'a aucune raison de passer.

    ensuite, c'est mon interprétation, il faudrais sûrement demander confirmation aux fabricants de compilateurs.
    Méphistophélès
    Si la solution ne résout pas votre problème, changez le problème...
    Cours et tutoriels C++ - FAQ C++ - Forum C++.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Citation Envoyé par méphistopheles Voir le message
    A mon avis, il considère simplement les membres des classes membres comme des membres et les fonctions membres des classes membres comme des fonctions membres. ce qui justifie (1) et (2). En un sens, c'est logique puisqu'une classe a toujours accès aux variables de son bloc/fichier.

    Par contre aucune règle ne permettant d'accéder aux membres privés de ses membres, (3) n'a aucune raison de passer.

    ensuite, c'est mon interprétation, il faudrais sûrement demander confirmation aux fabricants de compilateurs.
    Attention, normalement, une classe n'a acces qu'aux (variable ou fonctions) membres publiques des variables membres qui la composent...

    Le fait d'imbriquer une classe ne devrait, normalement, changer que le scope dans lequel cette classe est connue, sans influer sur la connaissance que la classe imbriquée (respectivement imbriquante) a de la classe imbriquante (respectivement imbriquée).

    Maintenant, il n'est pas exclu qu'il y ait certaines difficultés techniques à mettre ce fait en pratique

    Mais le mieux serait de s'adresser directement aux dev de Gcc ou de visual afin de savoir ce qu'il en est
    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

  5. #5
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Salut,
    Attention, normalement, une classe n'a acces qu'aux (variable ou fonctions) membres publiques des variables membres qui la composent...
    C'est bien pour ça que le (3) ne marche pas, mais cette règle n'interdit pas (1) et (2) puisque ceux cis accèdent non paas à leurs membres, mais aux variables des blocs parents ! (pas au sens de l'héritage bien sûr)

    Citation Envoyé par koala01 Voir le message
    Le fait d'imbriquer une classe ne devrait, normalement, changer que le scope dans lequel cette classe est connue, sans influer sur la connaissance que la classe imbriquée (respectivement imbriquante) a de la classe imbriquante (respectivement imbriquée).

    Maintenant, il n'est pas exclu qu'il y ait certaines difficultés techniques à mettre ce fait en pratique

    Mais le mieux serait de s'adresser directement aux dev de Gcc ou de visual afin de savoir ce qu'il en est
    Je suppose qu'ils se sont dit qu'on avais qu'a déclarer nos classe dont on voulait interdire l'accès comme des classes externes, bien que ça ne permette pas une interdiction totale d'accès à l'utilisateur.

    En même temps, cette version là est bien pratique, ça évite d'écrire un friend de plus
    Méphistophélès
    Si la solution ne résout pas votre problème, changez le problème...
    Cours et tutoriels C++ - FAQ C++ - Forum C++.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par méphistopheles Voir le message
    En même temps, cette version là est bien pratique, ça évite d'écrire un friend de plus
    jusqu'au jour où tu passera sur un compilateur qui respecte ce point de la norme (s'il y en a un ) et où tu te fera jeter comme un malpropre parce que l'amitié n'est pas déclarée

    Ceci dit, c'est bel et bien un bug (reconnu comme tel par Gcc: http://gcc.gnu.org/bugs/#known sous le numéro 45 )
    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

  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 koala01 Voir le message
    Ceci dit, c'est bel et bien un bug (reconnu comme tel par Gcc: http://gcc.gnu.org/bugs/#known sous le numéro 45 )
    Ce qui est surprenant c'est qu'il soit aussi sur Visual. Quand le même bug est sur 2 compilos, même si ce n'est pas représentatif, j'ai plus de doute sur ma compréhension de la norme.
    Si d'autres intervenants ont des compilos pour tester, ce serait intéressant de connaître leur comportement.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Je ne serais pas plus étonné que cela si l'on venait me dire que c'est du à un problème dont le parser ou le lexer sont implémentés...

    Pour peu qu'ils le soient de manière plus ou moins similaire sous Gcc et sous VC, il devient relativement cohérent que le même problème se pose sous les deux

    Maintenant, peut être la norme présente-t-elle une règle qu'il est matériellement (enfin, on se comprend sur le terme hein) impossible de suivre dans l'état actuel des choses
    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

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 69
    Points : 62
    Points
    62
    Par défaut
    1/ Merci à tous pour les réponses très claires.

    2/ La norme serait donc 'incompatible' avec la STL?!

    En effet, j'aime écrire des sous classes dans des fonctions. Par exemple pour écrire des foncteurs. Et bien je me fais jeter par Visual quand je la déclare en friend (qui me dit qu'il est interdit dans une fonction de déclarer en friend des sous classes locales à une fonction).

    Bref, sans ce 'bug', plus de foncteurs, sauf remontés / déclarés en tant que classes (et non sous classes) !

    Ou alors je me trompe complètement (ce qui est fort probable)?

  10. #10
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Citation Envoyé par ElPedro Voir le message
    1/ Merci à tous pour les réponses très claires.

    2/ La norme serait donc 'incompatible' avec la STL?!
    J'en doute ... La stl étant le résultat des précédentes normes...

    Citation Envoyé par ElPedro Voir le message
    En effet, j'aime écrire des sous classes dans des fonctions. Par exemple pour écrire des foncteurs. Et bien je me fais jeter par Visual quand je la déclare en friend (qui me dit qu'il est interdit dans une fonction de déclarer en friend des sous classes locales à une fonction).

    Bref, sans ce 'bug', plus de foncteurs, sauf remontés / déclarés en tant que classes (et non sous classes) !

    Ou alors je me trompe complètement (ce qui est fort probable)?
    Je ne sais pas s'il est possible d'écrire des classes dans des fonctions (jamais essayé, jamais posé la question), mais par contre, un foncteur n'est pas une classe dans une fonction, mais une sous-classe d'une classe, sous-classe elle-même munie d'un opérateur double parenthèses du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Classe
    {
       class Foncteur_comp
       {
          operator()(const Classe &,const Classe &);
       };
    };
    pour un foncteur de comparaison.

    (si l'on ne pouvait faire de foncteur sous VC++, je crois pas que grand monde l'utiliserait... déjà que pour l'optimisation en vitesse c'est pas ça....)
    Méphistophélès
    Si la solution ne résout pas votre problème, changez le problème...
    Cours et tutoriels C++ - FAQ C++ - Forum C++.

  11. #11
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Je ne sais pas s'il est possible d'écrire des classes dans des fonctions
    Si des classe locales à des fonctions, c'est possible, et y'a quelques applications. (ça court pas les rues).
    Quand on foncteur jvois pas où vous voulez en venir :
    un foncteur est par définition un objet qui peut avoir la sémantique d'une fonction. (un classe surchargeant l'op())
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 69
    Points : 62
    Points
    62
    Par défaut
    >>(jamais essayé, jamais posé la question)
    C'est extrêmement courant. C'est une technique basique très utile pour circonscrire le code à des fonctions, et pour écrire certaines macro.

    >>un foncteur n'est pas une classe dans une fonction, mais une sous-classe d'une classe
    Désolé, mais un foncteur est juste une classe (avec l'operator()).

    >>>La stl étant le résultat des précédentes normes...
    Encore raté, la stl a été intégrée dans la norme (après avoir été écrite par Stepanov). D'ailleurs le dernier papier 'on iterator' (qui est sorti il y a 2 jours) de A.Alexandrescu revient là dessus.

    >>>déjà que pour l'optimisation en vitesse c'est pas ça....
    Ben voyons ^^!

    L'idée est que certes la STL est certes utilisable, mais sans ce fichu friend, on perd encore plus au niveau ergonomie du code entre "l'endroit où la fonction est utilisée" et "l'endroit où la fonction est codée".

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 69
    Points : 62
    Points
    62
    Par défaut
    @Goten
    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
     
    class CBase
    {
        int mMember; // private
        void doSomething(std::list<CBase>& pVec);
    };
     
    // cpp:
    void CBase::doSomething(std::list<CBase>& pVec)
    {
        struct CFoncteur
       {
            void operator()(CBase& c)
            {
                  c.mMember = 3; // acces membre private!
             }
       };
     
       std::for_each(pVec.begin(), pVec.end(), CFoncteur());
     
    }
    Ce code n'est pas valide d'après la norme.

  14. #14
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Et c'est pour ça qu'on inventa les lambda :'). Sinon ouai à chaud là je vois pas d'autre solutions que d'écrire un accesseur. Mais j'ai pas les idées trop en place, peut être que quelqu'un verra une solution plus élégante.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  15. #15
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Citation Envoyé par koala01 Voir le message
    jusqu'au jour où tu passera sur un compilateur qui respecte ce point de la norme (s'il y en a un ) et où tu te fera jeter comme un malpropre parce que l'amitié n'est pas déclarée

    Ceci dit, c'est bel et bien un bug (reconnu comme tel par Gcc: http://gcc.gnu.org/bugs/#known sous le numéro 45 )
    ??
    Au contraire, cette page liste le comportement "Nested classes can access private members and types of the containing class." dans la catégorie "Non-bugs" car c'est le comportement préconisé par le comité dans le defect 45 !

  16. #16
    screetch
    Invité(e)
    Par défaut
    scrogneugneu bon peut etre je reviens de soirée et je suis pas de bonne humeur, mais suis-je le seul a etre exaspéré par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class C {  // entire body is private
    qui pourrait etre ecrit sans commentaire
    juste pour la clarté ? (oui je chipotte)

  17. #17
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Jsuis du même avis.. mais bon c'était qu'un test case so...
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    A vrai dire, je suis dans les premiers à m'autoriser un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class MaClass
    {
        /* des typedef (privés) voire, des classes imbriquée
         * à usage interne de la classe
         */
        public:
        /* interface publique */
        private:
        /* membres privés */
    }
    Mais, je suis d'accord avec toi que, quitte à placer un commentaire pour rappeler que la visibilité par défaut d'une classe est private, il est bien plus opportun de, simplement, le signaler explicitement
    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

  19. #19
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 69
    Points : 62
    Points
    62
    Par défaut
    Merci mille fois Azrar!
    Bien vu!

    Thread complété!

    Edit : Arf j'avais pas vu qu'il y avait une seconde page . Effectivement, pas de soucis, j'utilise toujours public: private: mais je voulais ne pas encombrer le code. Encore merci à tous!

    EDIT2:
    En fait c'est le comportement "conseillé", mais cependant il ne fait actuellement pas partie de la norme. Le defect 45 est de statut DR, et non TC1. Par conséquent il n'a pas été intégré dans la norme, bien qu'il ait été discuté en 1998 (cf "ONLY RESOLUTIONS FOR ISSUES WITH TC1 STATUS ARE PART OF THE INTERNATIONAL STANDARD FOR C++").

  20. #20
    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 Arzar Voir le message
    ??
    Au contraire, cette page liste le comportement "Nested classes can access private members and types of the containing class." dans la catégorie "Non-bugs" car c'est le comportement préconisé par le comité dans le defect 45 !
    En somme, il s'agissait d'une certaine ambiguïté résolue vers les classes contenues sont considérées comme des membres de la classe contenant et ont donc les mêmes accès qu'une méthode par exemple. D'où, les compilo qui accepte ce code.
    Merci Arzar pour cette précision chirurgicale

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

Discussions similaires

  1. un cas avec des Sous Classes
    Par Daeron dans le forum Langage
    Réponses: 7
    Dernier message: 17/01/2006, 17h39
  2. Declaré en classe de base, instancié en sous classe
    Par jobigoud dans le forum Langage
    Réponses: 3
    Dernier message: 14/11/2005, 10h55
  3. Super classes et sous-classes/Méthodes
    Par smag dans le forum Langage
    Réponses: 4
    Dernier message: 29/06/2005, 23h10
  4. [Language]constructeur de sous classes
    Par seb888 dans le forum Langage
    Réponses: 12
    Dernier message: 04/06/2005, 22h37
  5. sous-classe de JPanel ou de JSpinner ?
    Par etiennegaloup dans le forum Composants
    Réponses: 3
    Dernier message: 06/03/2005, 18h55

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