web-dev-qa-db-fra.com

Les classes internes peuvent-elles accéder à des variables privées?

class Outer {

    class Inner {
    public:
        Inner() {}
        void func() ;
    };

private:
    static const char* const MYCONST;
    int var;
};

void Outer::Inner::func() {
    var = 1;
}

const char* const Outer::MYCONST = "myconst";

Cette erreur se produit lorsque je compile avec la classe Outer :: Inner 'n'a pas de membre nommé `var'

104
kal

Une classe interne est un ami de la classe dans laquelle elle est définie.
Donc oui; un objet de type Outer::Inner peut accéder à la variable membre var d'un objet de type Outer.

Contrairement à Java cependant, il n’existe aucune corrélation entre un objet de type Outer::Inner et un objet de la classe parente. Vous devez créer la relation parent-enfant manuellement.

#include <string>
#include <iostream>

class Outer
{
    class Inner
    {
        public:
            Inner(Outer& x): parent(x) {}
            void func()
            {
                std::string a = "myconst1";
                std::cout << parent.var << std::endl;

                if (a == MYCONST)
                {   std::cout << "string same" << std::endl;
                }
                else
                {   std::cout << "string not same" << std::endl;
                }
            }
        private:
            Outer&  parent;
    };

    public:
        Outer()
            :i(*this)
            ,var(4)
        {}
        Outer(Outer& other)
            :i(other)
            ,var(22)
        {}
        void func()
        {
            i.func();
        }
    private:
        static const char* const MYCONST;
        Inner i;
        int var;
};

const char* const Outer::MYCONST = "myconst";

int main()
{

    Outer           o1;
    Outer           o2(o1);
    o1.func();
    o2.func();
}
108
Martin York

Une classe interne a accès à tous les membres de la classe externe, mais ne comporte pas de référence implicite à une instance de classe parent (contrairement à certaines bizarreries avec Java). Ainsi, si vous transmettez une référence à la classe externe à la classe interne, elle peut faire référence à tout élément de l'instance de classe externe.

25
MSN

Tout ce qui est partie of Outer devrait avoir accès à tous ses membres, publics ou privés.

Edit: votre compilateur est correct, var n'est pas membre d'Inner. Mais si vous avez une référence ou un pointeur sur une instance de Outer, il pourrait y accéder.

6
Mark Ransom

var n'est pas un membre de la classe interne.

Pour accéder à var, vous devez utiliser un pointeur ou une référence à une instance de classe externe. par exemple. pOuter-> var fonctionnera si la classe interne est un ami d’extérieur, ou si var est publique, si l’on suit strictement la norme C++.

Certains compilateurs traitent les classes internes comme des amis de l'extérieur, mais d'autres non. Voir ce document pour le compilateur IBM :

"Une classe imbriquée est déclarée dans l'étendue d'une autre classe. Le nom d'une classe imbriquée est local par rapport à sa classe englobante. Sauf si vous utilisez des pointeurs, des références ou des noms d'objet explicites, les déclarations d'une classe imbriquée ne peuvent utiliser que des constructions visibles, notamment tapez des noms, des membres statiques et des énumérateurs de la classe englobante et des variables globales.

Les fonctions membres d'une classe imbriquée respectent les règles d'accès habituelles et ne disposent d'aucun privilège d'accès spécial pour les membres des classes qui les entourent. Les fonctions membres de la classe englobante n'ont pas d'accès spécial aux membres d'une classe imbriquée. "

1
xiaochuanQ