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 :

protected : portée d'instance et non de classe ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    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 protected : portée d'instance et non de classe ?
    Bonjour,

    je suis tombé sur un résultat assez surprenant en compilant le code suivant :

    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
     
    class A
    {
     
    public:
     
        virtual ~A() {}
        void activate(bool is_active) { activate_impl(is_active); }
     
    protected:
     
        virtual void activate_impl(bool is_active) { std::cout << "activate in A" << std::endl; }
     
    };
     
    class B : public A
    {
     
    public:
     
        B() : p_a(new A) {}
        virtual ~B() { delete p_a; }
     
    protected:
     
        virtual void activate_impl(bool is_active) { p_a->activate_impl(is_active); }
    };
    J'obtiens le message d'erreur suivant : cannot access protected member declared in class A. Testé avec Visual Studio 2008 et g++ 4.

    Je trouve cela étrange dans la mesure où B dérive bien de A, je pensais que, de la même manière que le mot clé private, la portée du mot clé protected était une portée de classe et non d'instance.

    Si quelqu'un a une explication, je suis preneur

    Merci d'avance.

  2. #2
    screetch
    Invité(e)
    Par défaut
    tu peux utiliser les méthodes protected sur toi même pas sur une autre instance.
    Ton B la, c'est déjà un A et en plus il possède un pointeur sur un autre A, je pense donc que tu n'as pas tout compris a l'héritage (peut-être tu as compris mais ce code me semble suspicieux), si tu as des cours il faudrait les revoir.

  3. #3
    Membre Expert Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Par défaut
    je ne suis pas une lumière dans ce domaine, mais le mot clé virtual ne jouerait pas aussi ?

    Et vu que tu as rédéfini activate_impl dans B, celle de A n'est plus accessible. Tu as cassé l'héritage.

  4. #4
    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
    @ screetch :

    Ce code est juste une simplification permettant de reproduire le problème, dans la réalité j'ai un pattern Decorator, donc rien d'anormal à dériver de A et avoir un pointeur sur A ; dans le vrai code, A est abstraite et mon p_a est une autre classe dérivée, mais peu importe encore une fois ce code est là pour reproduire le problème et rien de plus.

    La méthode qui m'intéresse est mise en protected car je souhaite qu'elle soit utilisable par mes différents decorators, mais pas par l'exterieur de la lib.

    J'ai bien vu que les méthodes protected ne sont appelables que sur une même instance, ma question est pourquoi un comportement différent du mot clé private ?

    @fregolo52 :

    Le mot clé virtual est hors de cause, on peut reproduire le même problème en appelant une méthode protected non virtual de A depuis une méthode public de B. De plus redéfinir une méthode virtuelle dans une classe dérivée n'empêche pas l'accès à la méthode de la classe mère (sur la même instance), il suffit de préciser A:: avant l'appel de la méthode.

  5. #5
    screetch
    Invité(e)
    Par défaut
    ah dakodak je comprends (pardon de prendre pour des débutants mais ici c'est le cas le plus fréquent )
    le pattern a été "inventé" récemment, ce cas n'était sans doute pas prévu a l'origine
    de plus le mot-clé "friend" ne convient pas forcément (friend selectionne les classes qui vont avoir accès a la méthode, et ca bloque la création de nouveaux décorateurs)
    mais c'est le plus proche de ce dont tu as besoin

  6. #6
    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
    Citation Envoyé par screetch Voir le message
    ah dakodak je comprends (pardon de prendre pour des débutants mais ici c'est le cas le plus fréquent )
    Pas de souci

    le pattern a été "inventé" récemment, ce cas n'était sans doute pas prévu a l'origine
    de plus le mot-clé "friend" ne convient pas forcément (friend selectionne les classes qui vont avoir accès a la méthode, et ca bloque la création de nouveaux décorateurs)
    mais c'est le plus proche de ce dont tu as besoin
    En fait j'utilise le "friend" pour résoudre mon pb, mais avec une classe intermédiaire friend de la class A, et une méthode publique utilisée par les decorators, redirigeant vers la méthode protected. Cela me permet de contourner le blocage de la création de nouveaux decorators. Par contre je trouve ça un peu bricolo

  7. #7
    Membre éclairé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Par défaut
    Bonjour,
    un autre contournement du problème peut être de créer un méthode static protected :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class A
    { 
    public:
        //[...]
     
    protected:
        static void call_activate_impl(A & a, bool is_active) 
        { a.activate_impl(is_active); }
        //[...]
    };
    Cette méthode est uniquement accessible depuis les classes dérivées et permet d’appeler la méthode interne voulue.
    Après je ne saurais dire si c'est plus propre/moins bricolage .

  8. #8
    Membre Expert Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Par défaut
    Citation Envoyé par bolhrak Voir le message
    De plus redéfinir une méthode virtuelle dans une classe dérivée n'empêche pas l'accès à la méthode de la classe mère (sur la même instance), il suffit de préciser A:: avant l'appel de la méthode.
    pouhaaa !!!! faut que je dorme !!!! Je n'avais pas vu que tu appelais la méthode de A dans B.
    Désolé pour mon message à la con.

Discussions similaires

  1. Variable d'instance et variable de classe
    Par glycerine dans le forum C++
    Réponses: 6
    Dernier message: 02/03/2015, 13h37
  2. Portée d'instance de classe.
    Par Mornor dans le forum Général Java
    Réponses: 12
    Dernier message: 09/12/2013, 22h33
  3. communication Port Usb en mode non bloquant
    Par laurentleroy dans le forum C
    Réponses: 4
    Dernier message: 28/10/2007, 23h29
  4. checker si un port est utilisé ou non
    Par Jérémy Lefevre dans le forum Flash
    Réponses: 7
    Dernier message: 06/06/2007, 14h23
  5. Réponses: 3
    Dernier message: 13/09/2006, 17h27

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