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 :

Problème encapsulation C++


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 21
    Par défaut Problème encapsulation C++
    Bonjour!

    J'ai un petit problème. J'ai une classe qui a été définie comme membre d'une autre classe
    voilà comment je procède pour coder les differentes methodes de la classe 2

    classe1::classe2::method()

    il se trouve que la classe 2 est un membre protected de la classe1

    A l'interieur d'une methode de la classe 2, j'aimerais acceder à certains membres protected de la classe 1 et le compilateur me dit que c'est pas possible

    en gros j'ai un membre classe protected qui veut dans l'une de ses methodes avoir accès à un membre protected de la classe dans laquelle elle est definie..

    Est ce normal que je puisse pas y avoir accès?

  2. #2
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    Oui c'est normal, les classes imbriquées en C++ n'ont pas de privilège d'accès sur les classes encapsulantes.

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

    Informations professionnelles :
    Activité : aucun

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

    La classe "classe2" n'est pas définie comme membre de la classe "classe1" mais comme... classe imbriquée... fusse-elle une classe "anonyme"

    Le fait que, par la suite, tu aie déclaré un membre du type de la classe imbriquée ne changera rien

    Il faut savoir que, dés le moment où tu utilise le mot clé class pour définir une nouvelle structure, tu encapsule irrémédiablement tout ce qu'elle peut contenir.

    C'est exactement ce qui se passe avec les espaces de nommages:
    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
     
    namespace MonNameSpace
    {
        void foo(MaClasse&);
        class MaClasse
        {
             public:
                /*foo a acces a tout ce qui est public ... */
             protected :
                /*... mais à rien de ce qui est protected ... */
             private:
                /* ... ou private ...*/
        };
     
    };
    Si tu veux que, dans ton exemple, classe1 puisse accéder directement aux membres protected et/ou private de classe2, il faudra signaler l'amitié de classe1 pour classe2 , ce qui ne change d'ailleurs absolument pas de ce qui doit être fait avec deux classes bien distinctes...

    Le fait de déclarer des classes imbriquées n'apporte, en réalité, qu'un seul avantage par rapport à celui de déclarer des classes distinctes, et qui est celui que l'on retrouve dans l'utilisation des espaces de nommage: le nom du type créé devient "dépendant" de l'espace de nommage/la classe dans le(la)quel(le) il est défini, et peut donc être réutilisé ailleurs
    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 averti
    Inscrit en
    Octobre 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 21
    Par défaut problème encapsulation
    dans ce cas dans une structure de classe imbriquées:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class classe1
    {
       protected:
       Methode_classe1() ;
     
       class classe2
       {
         protected:
         membre_classe2 ;
       }
    }
    Comment je dois procéder pour pouvoir avoir accès à membre_classe2 en etant dans l'ecriture de la definition de Methode_classe1() ?
    Ou comment puis-je modifier la valeur de membre_classe2 en etant dans Methode_classe1()?

    Je vous remercie d'avance

  5. #5
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Il te faut 1) une instance de la classe intérieure 2) un couple accesseur/mutateur pour ton attribut

  6. #6
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 21
    Par défaut reponse a Alp
    désolé Alp mais franchement je suis un debutant j'ai rien compris à la 2)
    c'est quoi un couple accesseur/mutateur?

    merci

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    ou
    1. une instance de la classe supérieure
    2. déclarer la classe supérieure comme amie de la classe imbriquée.


    Au final, tu as donc deux solutions:

    Celle proposée par Alp () qui prend la forme de
    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
    35
    36
    37
    38
    39
    40
    41
     
    class Classe1
    {
         public:
        class classe2
        {
            public:
                Classe2();//constructeur
                ~Classe2();//destructeur
                /*const */ type /*&*/ GetMembre()/*const*/
                {
                    return membre_classe2;
                }
                void SetMembre(/*const*/ type /*&*/ newval)
                {
                     membre_classe2=newval;
                }
            protected:
                type membre_classe2 ;
        };
             Classe1();//constructeur
             ~Classe1();//destructeur
             /*const */ type /*&*/ GetMembreClass2()/*const*/
             {
                 return m1.GetMembre();
             }
             /* voir, pourquoi pas */
             void ModifyMembreClass2(/* const */ type /*&*/ newval)
             {
                  m1.SetMembre(newval);
             }
        protected:
        Methode_classe1()
        {
             type laval=m1.GetMembre();
             /* voir */
             m1.SetMembre( nouvelle_valeur_de_type_type);
        }
        private:
            Classe2 m1;
    };
    qui permet une utilisation sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /*soit, on travaille uniquement avec Classe2 */
    Classe1::Classe2 obj;
    /* pour la modification du membre */
    obj.SetMembre(nouvelle_valeur);
    /*ou, pour l'acces au membre */
    type lemembre=obj.GetMembre();
    /* soit on travaille uniquement avec Classe1 */
    Classe1  autre_obj();
    /* pour récupérer la valeur */
    type lemembre_de_m1=autre_obj.GetMembreClass2();
    /* pour modifier la valeur */
    autre_obj.ModifyMembreClass2(nouvelle_valeur);
    Ou, si tu estimes peu cohérent de permettre de modifier la valeur du membre autrement que par l'accès via Class1, tu peux envisager une relation d'amitié sous la forme de
    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
     
    class Classe1
    {
        public:
        class classe2
        {
            public:
                Classe2();//constructeur
                ~Classe2();//destructeur
          /* ni mutateur, ni accesseur... Personne n'a acces à membre_class2*/
            private:
                type membre_classe2 ;
                /* sauf Class1, grâce à l'amitié */
                friend class Class1;
        };
            Classe1();//constructeur
            Classe1();//destructeur
             /*const */ type /*&*/ GetMembreClass2()/*const*/
             {
                 return m1.membre_classe2;
             }
             /* voir, pourquoi pas */
             void ModifyMembreClass2(/* const */ type /*&*/ newval)
             {
                  m1.membre_classe2=newval;
             }
        private:
            Classe2 m1;
     
    };
    Tu pourras alors créer sans problème un objet de type Classe2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Classe1::Classe2 objet; /* aucun problème: le constructeur de
                              * Classe2 est public
                              */
    mais le seul moyen de modifier la valeur de membre_classe2 passera par l'utilisation d'un objet de type Classe1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    /* aucun acces à objet.membre_classe2, car il est privé ...
     * par contre tu peux y accéder par Classe1
     */
    Classe1 autre_objet;
    /* pour récupérer la valeur */
    type val=autre_objet.GetMembreClass2();
    /* ou pour en changer la valeur */
    autre_objet.ModifyMembreClass2(la_nouvelle_valeur);
    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

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par LePetitBricoleur Voir le message
    désolé Alp mais franchement je suis un debutant j'ai rien compris à la 2)
    c'est quoi un couple accesseur/mutateur?

    merci
    Accesseur et mutateur ne sont que des méthodes (publiques) pour lesquelles on précise ce qu'elles sont sensées faire:
    • un accesseur va permettre d'obtenir une valeur (les fameuses méthodes GetMembre() et GetMembreClass2() de mes exemples)
    • un mutateur va permettre de... modifier la valeur d'un membre (les fameuses méthodes SetMembre() et ModifyMembreClass2() de mes exemples)


    En anglais, on parle souvent de "getters" et de "setters"
    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

  9. #9
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 21
    Par défaut classes imbriquées probleme
    En fait le truc c'est que dans la classe 1 pour la methode Method_classe1
    j'aimerais pouvoir modifier la valeur de Membre_classe2

    void classe1::Method_classe1()
    {
    Membre_classe1=.... ;
    }

    comment faire pour pouvoir avoir accès à Membre_classe2 à l'interieur de Method_classe1

  10. #10
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 21
    Par défaut problème classe imbriquées
    ok! je crois avoir compris
    Tout a l'heure mon dernier message a été envoyé avant de lire vos reponses
    Je vous remercie beaucoup pour cette aide

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    En suivant les exemples que j'ai fournis

    En fait, il y a deux solutions encore:
    1. Soit la Classe1 dispose d'un membre de type Classe2, et ce sont les exemples fournis
    2. Soit, la Classe1 n'a pas de membre de type Classe2, et il s'agira alors de fournir un objet de type Classe2 comme paramètre (référence constante si lecture seule, référence non constante si tentative de modification)

    Mais, quoi qu'il en soit, il faudra passer par une intance de type Classe2, selon le cas:
    • m1.GetMembre(),
    • m1.SetMembre(valeur),
    • m1.membre_classe2,

    ou m1 est soit membre de la classe Classe1, soit parametre fournis à la méthode
    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

  12. #12
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 21
    Par défaut problème classes imbriquées
    Mais bon...c'est pas vraiment la meme chose..là dans les explications que vous m'avez donné si j'ai bien compris il faut instancier les classe et utiliser des fonctions pour modifier ou setter les membres de classe 2.

    moi ce que je veux faire c'est vraiment setter les membres de classe2 dans une methode de classe 1 (en gros dans le code de Method_class1 pouvoir à un moment dire membre_classe2 vaut ...)

    suis-je alors obliger dans le code de Method_class1 d'instancier encore un objet class1? ça devient redondant non?

  13. #13
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 21
    Par défaut problèmes classes imbriquées
    ok! ça y est j'ai compris
    désolé du message précédent j'avais pas très bien compris...je viens de comprendre. En gros c'est tout con..il faut juste disposer d'un membre classe2 et ensuite hop hop

    merci beaucoup

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Non...

    Si tu veux modifier la valeur de membre_classe2 dans Classe1, il faut:
    1. que tu aies une instance de type Classe1 pour pouvoir appeler la méthode (SetMembreClasse2()) (à moins que ce ne soit une méthode statique, mais on ne va pas t'embrouiller d'avantage avec cela )
    2. au choix
      • Soit que la classe Classe1 dispose d'un membre de type de Classe2
      • Soit fournir une référence de type Classe2 comme paramètre à la méthode (SetCMembreClasse2())

    Où est la redondance, là dedans

    Ou, plutôt, que ne comprend tu pas dans l'idée

    Ainsi, en reprenant l'exemple où seul Classe1 doit pouvoir accéder au membre de Classe2, mais en l'adaptant pour que Classe1 n'aient pas de membre de type de Classe2, cela deviendrait:
    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
     
    class Classe1
    {
        public:
            class Classe2
            {
                public:
                    Classe2();//constructeur
                    ~Classe2();//destructeur
             /* pas d'acces  à membre_classe2, car aucun mutateur/accesseur*/
                private:
                    type membre_classe2;
                    /* sauf pour Classe1, parce qu'elle est déclarée amie */
                    friend class Classe1;
            };
            Classe1();
            ~Classe1();
            /* modifier la valeur */
            void SetClasse2Member( Classe2& mod, /*const*/ type /*&*/ newval)
            {
                mod.membre_classe2=newval;
            }
            /* récupérer la valeur */
            /*const*/ type/*&*/GetClass2Member(const Classe2& toget) const
            {
                 return toget.membre_classe2;
            }
     
    };
    L'utilisation en deviendrait
    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
     
    /* Création d'un objet de type Classe2 */
    Classe2 obj;
    /* on n'a aucun acces à obj.membre_classe2, donc il nous faut un objet
     * de type Classe1 pour y arriver 
     */
    Classe1 hasaccess;
    /* au travers de hasaccess, on peut maintenant accéder à 
     * obj.membre_classe2
     *
     * Soit pour en obtenir la valeur
     */
    type recup=hasaccess.GetClass2Member(obj);
    /* soit pour la modifier */
    hasaccess.SetClass2Member(obj, nouvelle_valeur_pour_membre_classe2);
    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. Problème de quotes dans du HTML encapsulé
    Par sub_zero dans le forum GWT et Vaadin
    Réponses: 2
    Dernier message: 02/12/2012, 13h45
  2. Problème d'encapsulation des MFCs
    Par RT222 dans le forum MFC
    Réponses: 3
    Dernier message: 27/09/2012, 11h35
  3. [CS4] Problème d'encapsulation de boutons
    Par Osef_ dans le forum ActionScript 1 & ActionScript 2
    Réponses: 1
    Dernier message: 09/01/2011, 22h48
  4. 2 floats dans une div, problème d'encapsulation
    Par student_php dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 15/11/2010, 16h30
  5. Problème encapsulation de scripts
    Par pitxu dans le forum Langage
    Réponses: 1
    Dernier message: 14/09/2007, 20h32

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