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 :

Classe imbriquée et accessibilité ?


Sujet :

C++

  1. #1
    Membre éclairé Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Par défaut Classe imbriquée et accessibilité ?
    Bonjour,

    Pour des besoins spécifiques j'ai mis dans mon code une classe imbriquée
    qui utilise une fonction membre (privée) de la classe hôte.
    voilà en gros ce que ça donne:
    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
     
    class A
    {
     
      class B
      {
        ...
     
        a->func();
      };
     
     
      void func();
     
      public:
     
      ...
     
    };
    le code compile et le prog fonctionne.

    Mais j'ai lu sur un forum qu'en fait une classe
    imbriquée utilisant une fonction ou variable membre
    privée de la classe hôte n'était pas accepté par tous les compilateurs.
    Apparemment les compilateurs Visual et Solaris rejettent
    ce code alors que Gcc l'accepte.

    Donc pour le cas où (j'utilise gcc), j'ai déclaré la fonction func() de A amie de
    la classe B (ce qui oblige à déclarer la fonction au tout début de la classe A).
    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
     
    class A
    {
      void func();
     
      class B
      {
        ...
     
        friend void A::func(); 
        a->func();
      };
     
      public:
     
      ...
     
    };
    Je voudrais savoir si mon code est correcte et
    qu'en est-il réellement de l'accessibilité.
    Est ce que ça dépend juste du compilateur ?


    Merci d'avance

  2. #2
    Membre éclairé Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Par défaut
    Argh! Je viens de me rendre compte que je me suis complètement
    planté sur la déclaration de fonction amie.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    friend void A::func();
    Si j'ai bien compris j'ai déclaré amie de la classe A la fonction
    func() membre de la classe B, ce qui dans mon cas n'a aucun intérêt.

    Après pas mal de tentatives et d'erreurs du compilo, je suis arrivé
    à la conclusion qu'il était finalement plus simple de déclarer
    carrément la classe B amie de la classe A.
    De cette façon B peut accéder a toutes les fonctions et
    variables membres de A, privé ou pas.
    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
     
    class B;
     
    class A
    {
      friend class B;
     
      class B
      {
        ...
     
        a->func();
      };
     
     
      void func();
     
      public:
     
      ...
     
    };
    Apparemment tout semble fonctionner.
    Mais ma question reste la même à savoir:
    Est ce que ce code est correcte et
    qu'en est-il réellement de l'accessibilité.


    Merci

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 636
    Par défaut
    Salut,

    La norme ne place que très peu de limites à la définition de classes imbriquées.

    Ainsi, il est même tout à fait possible de déclarer une classe imbriquée, mais de la définir en dehors de la classe hôte.

    La seule restriction dans ce cas sera qu'il faudra disposer de la définition de la classe imbriquée avant de pouvoir en créer une instance.

    En outre, une classe imbriquée faisant partie intégrante de la classe hôte, la classe imbriquée peut accéder à l'ensemble des membres et méthodes de la classe hôte, quelle qu'en soit l'accessibilité, et sans devoir recourir à l'amitié.

    Par contre, la classe imbriquée subit l'accessibilité au sein de laquelle elle a été déclarée dans la classe hôte.

    Il y a donc un foule de possibilité pour implémenter des classes imbriquées, mais il faut toujours faire attention à l'accessibilité dans laquelle elles sont déclarées

    Ainsi, le code suivant devrait très bien fonctionner avec les compilateurs qui respectent la norme:
    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
    class Hote
    {
        public:
            Hote(){}
            ~Hote(){}
            void fonction()
            { 
                Imbriquee i;
                i.f(*this);
            }
        private:
            class Imbriquee
            {
                public:
                    Imbriquee(){}
                    ~Imbriquee(){}
                    void f(Hote& h)
                    {
                         h.fonctPrivee();
                    }
            };
            void fonctPrivee(){}
    };
    mais il sera impossible de créer une instance de la classe Imbriquee en dehors de la classe Hote:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void fonctionExterne()
    {
        Hote::Imbriquee i; //Erreur: la classe Imbriquee est privee
    }
    Comme il est possible de définir la classe imbriquée en dehors de la classe hôte, la situation se présente comme ceci:
    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
     
    class Hote
    {
        class Imbriquee;//déclaration de la classe !!! ACCESSIBILITE PRIVATE !!!
        public:
            Hote(){}
            ~Hote(){}
            void badFunction()
            {
                /* cette fonction sera refusée à la compilation:
                 * la classe Imbriquee n'est pas définie lorsque l'on essaie
                 * d'en créer une instance
                 */
                Imbriquee i;
            }
            inline void goodFunction(); 
        private:
            void privateFunction(){}
    };
    class Hote::Imbriquee
    {
            public:
                imbriquee(){}
                ~Imbriquee(){}
                void f(Hote& h)
                {
                    h.privateFunction();
                }
    };
    void Hote::goodFunction()
    {
        Imbriquee i;
        i.f(*this);
    }
    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

  4. #4
    Membre éclairé Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Par défaut
    Merci pour toutes ces précisions ;)
    En outre, une classe imbriquée faisant partie intégrante de la classe hôte, la classe imbriquée peut accéder à l'ensemble des membres et méthodes de la classe hôte, quelle qu'en soit l'accessibilité, et sans devoir recourir à l'amitié.
    Oui c'est ce que j'avais cru comprendre. D'ailleurs avec gcc mon exemple
    compile parfaitement même sans les déclarations d'amitié.
    Ce qui m'a mis le doute c'est les infos lu sur un forum
    avec entre autre:
    11.8 Nested classes [class.access.nest]

    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 friend-
    ship to an enclosing class; the usual access rules (_class.access_)
    shall be obeyed. The members of an enclosing class have no special
    access to members of a nested class; the usual access rules
    (_class.access_) shall be obeyed. [Example:
    class E {
    int x;
    class B { };

    class I {
    B b; // error: E::B is private
    int y;
    void f(E* p, int i)
    {
    p->x = i; // error: E::x is private
    }
    };
    int g(I* p)
    {
    return p->y; // error: I::y is private
    }
    };
    --end example]

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 636
    Par défaut
    De fait... je m'étais arrêté à la section 9 sur le sujet

    Et je suis parti sur le principe que Gcc respectait la norme sur le sujet (re )

    Mais, effectivement, la section 11 précise que les classes imbriquées ne disposent pas d'un accès particulier en ce qui concerne la classe hôte

    il faut donc bien déclarer la classe imbriquée amie de la classe hôte si tu veux accéder aux éléments privés de celle-ci, et je soumet ce non respect de la norme à Gcc
    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

  6. #6
    Membre éclairé Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Par défaut
    Donc c'est gcc le mauvais élève qui respecte pas la norme
    C'est bon à savoir.
    Ceci dit c'est drôle que depuis tout ce temps les développeurs du
    projet gcc n'ont pas réglé ce pb.
    Peut être ont-ils une bonne raison de ne pas le faire ...bizzare !

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 636
    Par défaut
    J'ai effectué une recherche sur le bugzilla de gcc et n'ai rien trouver qui s'y rapportait.

    Je précise que j'utilise la version 4.3.1, et que je n'ai pas vérifié si le problème était présent sur d'autres versions.

    Quoi qu'il en soit, j'ai envoyé un rapport de bug, et nous verrons ce qu'il en sort
    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

Discussions similaires

  1. [C#]Remonter des événements dans des classes imbriquées
    Par Kcirtap dans le forum Windows Forms
    Réponses: 9
    Dernier message: 14/12/2013, 12h43
  2. Classe imbriquée et son constructeur
    Par toninlg dans le forum C++
    Réponses: 7
    Dernier message: 30/09/2006, 06h21
  3. Classe imbriquée
    Par dj.motte dans le forum C++
    Réponses: 10
    Dernier message: 13/04/2006, 07h34
  4. classes imbriquées
    Par smedini dans le forum C++
    Réponses: 10
    Dernier message: 10/12/2005, 13h16
  5. Intérêt des classes imbriquées ?
    Par elitost dans le forum Langage
    Réponses: 5
    Dernier message: 21/10/2005, 09h30

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