2010-04-22 5 views
16

HI,Question sur C++ classe interne

En C++ classe interne,

class A { 
    public: 
     void f1(); 
    private: 
     void f2(); 
    class B { 
     private void f3(); 
    }; 

} 

Est-ce une classe interne (B) a un pointeur vers la classe parente (A)? (comme il le fait en Java). Et B peut-il appeler la méthode publique/privée de sa classe parente (comme c'est le cas en Java).

Merci.

Répondre

28

Non - en C++, les classes d'imbrication n'affectent que les noms et la visibilité, et non la sémantique de la classe elle-même. En ce qui concerne le code généré, la classe imbriquée n'est pas différente de celle qui n'est pas imbriquée.

Tout ce qui a changé est la visibilité et le nom (par exemple, si elle est dans une section private: de la classe externe, ce n'est pas visible au monde extérieur, et si elle est dans une section public:, il est visible, mais (bien sûr) pour le nommer, vous utilisez outer_class::inner_class Il s'agit quand même d'une classe complètement distincte - juste par exemple, vous pouvez créer une instance de la classe interne sans créer d'instance de la classe externe

Editer: Désolé, j'ai raté une partie de En C++ 0x, la classe interne a accès aux parties privées de la classe externe - en gros, c'est comme si la classe externe avait déclaré la classe interne comme son ami, donc les noms privés sont visibles, mais vous encore besoin de passer quelque chose comme une référence à un objet de la classe externe avant qu'il puisse invoquer des fonctions membres non statiques de la classe externe.

Bien que cela ne soit pas encore le cas, je crois que la plupart des compilateurs implémentent déjà cette partie particulière.

+4

Il semble que cela change dans C++ 0x. C++ 03 dit: "Les membres d'une classe imbriquée n'ont aucun accès spécial aux membres d'une classe englobante." C++ 0x FCD dit: "Une classe imbriquée est un membre et en tant que tel a les mêmes droits d'accès que n'importe quel autre membre." (tous les deux §11.8/1). (Le changement a été introduit par CWG défauts 45 et 494: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#45 et http://www.open-std.org/ jtc1/sc22/wg21/docs/cwg_defects.html # 494) –

+0

Bon - cela supprime l'envie d'écrire 'friend class {', qui est supporté par certains compilateurs, mais ne fait évidemment pas du tout partie de la classe imbriquée! – Potatoswatter

+1

@Potato: Fait intéressant, même Comeau en mode C++ 03 strict ne suit pas le langage C++ 03. Cela me porte à croire que (a) il est probablement impossible pour une raison quelconque de suivre le langage C++ 03 (bien que je n'ai pas encore compris pourquoi, exactement, outre ce qui est mentionné dans les DRs ci-dessus), et (b) il est probable que personne ne suit réellement le langage C++ 03 :-). –

7

Non, la classe B ne possède pas de pointeur vers la classe A, sauf si vous l'ajoutez explicitement.

0

-t-il un pointeur vers le parent: Non
-t-il accès aux parents membres privés: Trier de

Je pense que le si elle a accès n'est pas bien défini dans la norme que je pourrais être faux.
Mais vous pouvez y accéder en g ++

#include <iostream> 

class X 
{ 
    class Y 
    { 
     public: 
      Y(X* p) 
       :parent(p) 
      {} 
      void TryY() 
      { 
       // Access a private member of X 
       ++(parent->value); 
      } 

     private: 
      X* parent; 
    }; 

    public: 
     X() 
      :y(this) 
     { 
      value = 4; 
     } 

     void TryY() 
     { 
      y.TryY(); 
      std::cout << value << std::endl; 
     } 
    private: 
     Y y; 
     int value; 

}; 

int main() 
{ 
    X x; 
    x.TryY(); 
} 
+0

Il devrait être un comportement incorrect pour C++ 03 selon * §11.8/1 *. –