69 votes

Les classes internes en C ++ sont-elles automatiquement des amis?

Si je définir une sous-classe en C++, est-il automatiquement un ami de la classe qui le contient? Par exemple, est-ce légal:

class Outer {
public:
    class Inner {
    public:
        void mutateOuter(Outer& o);
    };

private:
    int value;
};

void Outer::Inner::mutateOuter(Outer& o) {
    o.value ++; // Legal?  Or not?
}

Je demande parce que sur certains compilateurs j'ai essayé (VS2003) ce code ne fonctionne pas, mais je l'ai entendu au moins anecdotique que cela fonctionne sur certains compilateurs. Je ne peux pas trouver un article pertinent dans le C++ spec à ce sujet, et si quelqu'un peut citer quelque chose de spécifique qui permettrait de dire que c'est légal ou pas, ce serait super.

Merci beaucoup!

72voto

hcc23 Points 398

Après avoir demandé plus ou moins la même question ici de moi-même, je voulais partager l' (apparemment) mise à jour de réponse pour le C++11:

Cité de http://stackoverflow.com/a/14759027/1984137:

standard de $11.7.1

"Une classe imbriquée est membre et en tant que telle a les mêmes droits d'accès que tout autre membre. Les membres d'une classe englobante n'ont l'accès aux membres d'une classe imbriquée; l'habitude des règles d'accès doit être obéi"

et l'habitude d'accès, les règles stipulent que:

"Un membre d'une classe peut accéder à tous les noms de ce qui la classe a accès..."

des exemples précis a été donné dans la norme:

class E {
    int x;
    class B { };

    class I {
        B b; // OK: E::I can access E::B
        int y;
        void f(E* p, int i) {
            p->x = i; // OK: E::I can access E::x
        }
    };
}

40voto

Nawaz Points 148870

Pas de. Classe imbriquée ne peut pas accéder private et protected des membres de la classe englobante par défaut.

La Norme C++ (2003) dit dans $11.8/1 [classe.d'accès.nid],

Les membres d'une classe imbriquée ont pas de accès spécial aux membres d'une classe englobante, ni à des classes ou les fonctions qui ont accordé à l'amitié pour une classe englobante; l'habitude les règles d'accès (clause 11) doit être obéi. Les membres de l'enfermer la classe n'ont pas d'accès à les membres d'une classe imbriquée; l'habitude les règles d'accès (clause 11) doit être obéi.

Exemple de la Norme elle-même:

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
   }
};

16voto

Ise Wisteria Points 5852

Depuis l'interlocuteur semble avoir accepté l'une des réponses, c'est juste une supplémentation.
La norme semble avoir changé la spécification sur l'accessibilité.

§11.8/1 en C++98 états:

Les membres d'une classe imbriquée ont pas de accès spécial aux membres d'une classe englobante, ni à des classes ou les fonctions qui ont accordé à l'amitié pour une classe englobante; l'habitude les règles d'accès doit être obéi.

§11.8/1 dans N1804(après TR1) membres:

Une classe imbriquée est membre et en tant que tel a les mêmes droits d'accès que tout d'autres membres.

Je pense actuel compilateurs C++ obéir plus récente spécification.

4voto

templatetypedef Points 129554

Eh bien, je me sens bête de poser cette question maintenant car je viens de trouver la partie de la spécification qui couvre: §11.8/1:

Les membres d'une classe imbriquée ont pas accès spécial aux membres d'une classe englobante, ni à des classes ou des fonctions qui ont accordé à l'amitié, à une classe englobante; l'habitude des règles d'accès (clause 11) doit être obéi. Les membres d'une classe englobante n'ont accès aux membres d'une classe imbriquée; l'habitude des règles d'accès (clause 11) doit être obéi

(Mon emphase)

Donc, il semble que non, les classes internes ne sont pas spécialement des privilèges d'accès.

3voto

Je ne connais pas l'emplacement précis par cœur, mais je me souviens de lire les spécifications et de constater que toutes les données privées d'une classe sont cachées de toutes les autres classes, y compris les classes imbriquées.

Fondamentalement, l'imbrication d'une classe définit une certaine portée, pas des privilèges d'accès.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X