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 :

Héritage et accès aux données


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 6
    Par défaut Héritage et accès aux données
    Bonjour,

    J'aurai une question par rapport à l'héritage de classe.
    J'ai une classe mère Solution dans laquelle j'ai des données "protected" et une classe fille SolPVL.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Solution
    {
    protected:
      int nbLig;
      ...
    }
    class SolPVL : public Solution
    {
       ...
    }
    Si j'ai bien compris, mes données protected de Solution devraient alors être aussi protected dans SolPVL, non ?

    Pourtant, si j'appelle nbLig depuis une fonction de SolPVL, j'obtiens l'erreur suivante à la compilation :
    /home/spetit/logiciel/include/solution.hpp:44: error: `int Solution::nbLig' is protected
    solPVL.cpp:189: error: within this context
    Est ce que ça peut venir du compilateur (g++, j'ai essayé avec les versions 3.3.6 et 4.0.1).
    Y a t'il une autre solution que de mettre toutes les données en public (j'ai essayé et pas d'erreur dans ce cas).

    Merci.
    Stéphanie

  2. #2
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    C'est bizarre... chez moi je n'ai pas eu ce type de problème... (avec GCC comme compilateur)
    Est-ce que tu peux nous donner un code minimal qui reproduit cette erreur ?

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 399
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 399
    Par défaut
    Dans une classe fille, tu n'as pas accès aux données protected d'un autre objet.

    Ce que tu peux faire, c'est un pseudo-accesseur protected static (inline pour optimiser) dans la classe mère, qui te permette d'accéder aux données de l'autre objet.
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Solution
    {
    protected:
       int nbLig;
       static inline int GetNbLig(Solution const &sol)
          { return sol.nbLig; }
    }
    class SolPVL : public Solution
    {
       void UneFonction(Solution & sol)
       {
          int nLig = GetNbLig(sol);
       }
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    ????

    Les membres protected sont vu comme public en interne dans la classe, et private à l'extérieur, non ???
    Donc une classe fille devrait y avoir accès.

  5. #5
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    Citation Envoyé par poukill
    Donc une classe fille devrait y avoir accès.
    Oui, oui, l'instance d'une classe fille y a accès.
    Mais une instance d'une classe fille n'a pas accès aux membres protected d'une autre instance de la même classe fille. Je crois que c'est ce que voulais dire Médinoc.

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 399
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 399
    Par défaut
    J'ignore si c'est dans la norme, mais c'est en tout cas ce que j'ai constaté.

    Il semblerait qu'on n'ait accès aux variables protected/private d'un objet extérieur que dans la même classe, et non pas dans les classes parentes/dérivées.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 464
    Par défaut
    Citation Envoyé par Eusebe
    Oui, oui, l'instance d'une classe fille y a accès.
    Mais une instance d'une classe fille n'a pas accès aux membres protected d'une autre instance de la même classe fille. Je crois que c'est ce que voulais dire Médinoc.
    Je ne crois pas.

    D'ailleurs les droits d'accès aux membres (privés/protégés/publics) n'ont rien à voir avec les instances: toutes les instances d'une classe donnée se comportent rigoureusement de la même façon !

    C'est au niveau des déclarations des différentes classes que ça se joue.

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 399
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 399
    Par défaut
    Si on a le même résultat avec g++ (Eusebe) et Visual (moi), c'est qu'il doit en être ainsi dans la norme.

    Les accès "n'ayant rien à voir avec les instances" ne se propagent pas vers les classes filles.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    Citation Envoyé par rigobert
    D'ailleurs les droits d'accès aux membres (privés/protégés/publics) n'ont rien à voir avec les instances: toutes les instances d'une classe donnée se comportent rigoureusement de la même façon !
    Ah bon ?

    Tu veux dire que chez toi si tu définis une classe A avec un membre privé a, l'objet A1 peut directement agir sur le membre a de l'objet A2 (A1 et A2 étant des instances de A) ?

    On ne dois pas avoir les mêmes compilateurs alors

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 399
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 399
    Par défaut
    Eusèbe : Normalement, ça, c'est permis.
    C'est ce qui permet entre autres de simplifier le constructeur de copie pour ne pas avoir à utiliser des accesseurs pour les variables privées, par exemple.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Membre chevronné
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 464
    Par défaut
    Citation Envoyé par Eusebe
    Ah bon ?

    Tu veux dire que chez toi si tu définis une classe A avec un membre privé a, l'objet A1 peut directement agir sur le membre a de l'objet A2 (A1 et A2 étant des instances de A) ?

    On ne dois pas avoir les mêmes compilateurs alors
    Soit on ne parle pas de la même chose, soit j'en perds mon latin

    Chez moi (VC 7.1), ceci fonctionne sans problème:

    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
    class A
    {
    	public:
     
    		void Test1 (const A& aaa)
    		{
    			Fonction1 (aaa);
    		}
     
    		void Test2 (A& aaa) const
    		{
    			Fonction2 (aaa);
    		}
     
    	private:
     
    		int	a;
     
    		void Fonction1 (const A& aaa)
    		{
    			a = aaa.a;
    		}
     
    		void Fonction2 (A& aaa) const
    		{
    			aaa.a = a;
    		}
    };
     
    int main()
    {
    	A a0;
    	A a1;
     
    	a0.Test1 (a1);
    	a1.Test2 (a0);
     
    	return 0;
    }

  12. #12
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Eusèbe : Normalement, ça, c'est permis.
    Ha bon ??? Sérieux?

  13. #13
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 399
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 399
    Par défaut
    Rigobert: Oui, ça, ça marche.
    C'est quand il y a de l'héritage que ça se complique.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre chevronné
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 464
    Par défaut
    Citation Envoyé par Médinoc
    Rigobert: Oui, ça, ça marche.
    C'est quand il y a de l'héritage que ça se complique.
    Ok, je préfère ça, j'ai cru être passé un moment dans la 4ème dimension

    Maintenant, j'ai essayé ça, qui me parait correspondre au problème tel qu'il a été posé au départ :

    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
    42
    43
    44
    45
    46
    47
    48
    class A
    {
    	protected:
     
    		int	a_x;
    };
     
     
    class B : public A
    {
    	public:
     
    		void Test1 (B& b) const
    		{
    			Fonction1 (b);
    		}
     
    		void Test2 (const B& b)
    		{
    			Fonction2 (b);
    		}
     
    	protected:
     
    		int	b_x;
     
    		void Fonction1 (B& b) const
    		{
    			b.a_x	= a_x;
    			b.b_x	= b_x;
    		}
     
    		void Fonction2 (const B& b)
    		{
    			a_x		= b.a_x;
    			b_x		= b.b_x;
    		}
    };
     
    int main()
    {
    	B	b0, b1;
     
    	b0.Test1 (b1);
    	b1.Test2 (b0);
     
    	return 0;
    }
    Et ça fonctionne aussi sans problème sous VC7.1

  15. #15
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 399
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 399
    Par défaut
    Voici un exemple qui montre le problème.
    Les lignes en commentaires sont celles qui échouent forcément, puisqu'on s'attaque à du private de la clase mère.
    La ligne en gras est celle qui met en évidence le problème.
    Code C++ : 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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    #include <iostream>
    using namespace std;
    
    class CBase
    {
    private:
    	int m_privBase;
    protected:
    	int m_protBase;
    public:
    	int m_pubBase;
    };
    
    class CDerivee : public CBase
    {
    private:
    	int m_privDeriv;
    protected:
    	int m_protDeriv;
    public:
    	int m_pubDeriv;
    
    void Fonction(CDerivee *pObj);
    };
    
    
    void CDerivee::Fonction(CDerivee *pObj)
    {
    cout << "Valeurs perso :" << endl;
    cout << m_privDeriv;
    cout << m_protDeriv;
    cout << m_pubDeriv;
    //cout << m_privBase;
    cout << m_protBase;
    cout << m_pubBase;
    cout << endl;
    
    cout << "Valeurs de l'autre :" << endl;
    cout << pObj->m_privDeriv;
    cout << pObj->m_protDeriv;
    cout << pObj->m_pubDeriv;
    //cout << pObj->m_privBase;
    cout << pObj->m_protBase;	//ici, ça marche
    cout << pObj->m_pubBase;
    cout << endl;
    
    cout << "Valeurs de l'autre (base)  :" << endl;
    CBase *pBase = pObj;
    //cout << pBase->m_privBase;
    cout << pBase->m_protBase;	//ici, ça foire
    cout << pBase->m_pubBase;
    cout << endl;
    }
    Le tout, testé sous Visual C+ 8.0 et gcc version 2.95.4 20020320 [FreeBSD]
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    Oups, au temps pour moi, rigobert

    En fait, j'avais testé ça sur des classes héritées, et ça ne fonctionnait pas :/ Va falloir que je me repenche sur le sujet...

    Désolé

    Médinoc, je viens de tester ce code, et ça compile aussi :
    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
    class B
    {
        protected:
     
    		int	a;
    };
     
    class A : public B
    {
    	public:
     
    		void Test1 (const A& aaa)
    		{
    			a = aaa.a;
    		}
     
    		void Test2 (A& aaa) const
    		{
    			aaa.a = a;
    		}
    };
     
    int main()
    {
    	A a0;
    	A a1;
     
    	a0.Test1 (a1);
    	a1.Test2 (a0);
     
    	return 0;
    }
    Edit : grilled...

  17. #17
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 399
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 399
    Par défaut
    J'ai mis un moment à reproduire le problème, car au début ça marchait.
    C'est ensuite que j'ai compris qu'il fallait un pointeur sur la classe de base.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  18. #18
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    Citation Envoyé par Médinoc
    J'ai mis un moment à reproduire le problème, car au début ça marchait.
    C'est ensuite que j'ai compris qu'il fallait un pointeur sur la classe de base.
    En effet, c'est bien ça que j'avais essayé dans ma programmation, et qui ne fonctionnait pas (d'où ma conclusion un peu hative...).

  19. #19
    Membre chevronné
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 464
    Par défaut
    Citation Envoyé par Médinoc
    J'ai mis un moment à reproduire le problème, car au début ça marchait.
    C'est ensuite que j'ai compris qu'il fallait un pointeur sur la classe de base.
    En tout cas l'hypothèse du bug est peu plausible si ça le fait sur plusieurs compilos (au moins 3).
    D'un autre côté ça parait un peu space comme spécification (de la norme C++)...

  20. #20
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 6
    Par défaut
    Merci beaucoup pour toutes vos réponses, elles m'ont aidée à bien comprendre ce qu'il se passait. J'ai essayé de mon côté de faire un exemple pour vous montrer mais Médinoc a été plus rapide : c'est bien l'équivalent de la ligne en gras de son code qui me posait problème.
    Je vais donc faire des fonctions get pour les quelques variables de la classe mère dont j'ai besoin dans la classe fille.
    Merci !
    Stéphanie

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Héritage, Accès aux données ...
    Par Joad dans le forum C++
    Réponses: 14
    Dernier message: 28/04/2006, 12h16
  2. [SGBD]Optimiser le temps d'accès aux données (schéma BD)
    Par vsavoir dans le forum Décisions SGBD
    Réponses: 5
    Dernier message: 08/10/2004, 19h33
  3. [débutant] avoir accès aux données de la base BCDI 3
    Par Valichou dans le forum Bases de données
    Réponses: 7
    Dernier message: 06/05/2004, 14h13
  4. accès aux donnée d'un DBGRID
    Par relax_06 dans le forum C++Builder
    Réponses: 4
    Dernier message: 03/03/2004, 00h06
  5. [TDataModule] Intérêt de séparer les accès aux données?
    Par Cornell dans le forum Bases de données
    Réponses: 5
    Dernier message: 05/09/2003, 17h42

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