2009-10-22 7 views
7

Je rencontre des difficultés pour implémenter une classe imbriquée dont le constructeur est initialisé avec certains membres de données privées de la classe englobante.Membres de données privées 'access to enclosing class' imbriqués

Exemple:

Header File: 
class Enclosing { 
    //...Public members 
    //...Private members 
    int x, int y 
    class Inner; // Declaration for nested class 
}; 

Impl. File: 
// Stuff... 
class Enclosing::Inner { 
    explicit Inner() : foo(x), bar(y) // foo and bar are data members of Inner 
    //... 
}; 

je reçois une erreur invalid use of non-static data member. Y a-t-il quelque chose qui me manque quand il s'agit d'un accès de classe imbriqué aux membres de sa classe englobante?

Répondre

18

membres x et y sont membre de données non statique de Enclosing, ce qui signifie qu'ils n'existe que dans un objet concret de Enclosing classe. Sans objet concret, il n'existe pas de x ni de y. Pendant ce temps, vous essayez de faire référence à x et y sans objet. Cela ne peut pas être fait, ce que le compilateur essaie de vous dire.

Si vous voulez initialiser les membres Inner::foo et Inner::bar de x et y, vous devez passer un objet concret de type Enclosing dans le constructeur de la Inner. Par exemple

class Enclosing::Inner {  
    explicit Inner(const Enclosing& e) : foo(e.x), bar(e.y) 
    {} 
    //... 
}; 

note supplémentaire: dans l'original 98 C++ la classe intérieure n'a pas de privilèges spéciaux accède à la classe externe. Avec le compilateur C++ 98, vous devez donner à la classe interne les privilèges nécessaires (amitié) ou exposer les membres x et y comme public. Cependant, cette situation a été classée defect en C++ 98, et il a été décidé que les classes internes devraient avoir un accès complet aux membres de classe externes (même privés). Donc, si vous devez faire quelque chose de plus en ce qui concerne les privilèges d'accès dépend de votre compilateur.

+1

Merci. J'ai lu sur le défaut de C++ 98 en faisant des recherches sur le mien, et je ne savais pas quoi en faire. Merci d'avoir tout nettoyé. – trikker

8

Le problème avec votre code est not visibility, comme l'a souligné AndreyT, mais une instance de la classe Inner n'est pas liée à une instance concrète de la classe Enclosing. En d'autres termes, lors de la construction d'un Inner, le compilateur n'a aucun moyen de savoir quel objet doit prendre les valeurs x et y.

Vous devrez fournir explicitement une instance de la classe Enclosing au constructeur de la classe Inner comme si:

class Enclosing 
{ 
private: 
    int x; 
    int y; 

    class Inner 
    { 
    private: 
    int foo; 
    int bar; 

    public: 
    explicit Inner(const Enclosing& e) 
     : foo(e.x), bar(e.y) 
    { } 
    }; 
}; 
0

classe imbriquée ne peut pas accéder aux données de troènes membre d'enfermer class.compiler montrent une erreur si nous essayons d'accéder à un membre de troène de la classe de fermeture, il ne peut accéder au membre de données publiques de la classe de fermeture .....

Questions connexes