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 :

Impossible de limiter friend à une fonction


Sujet :

C++

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 413
    Par défaut Impossible de limiter friend à une fonction
    Bonjour à tous,
    J'ai une erreur avec le compilateur de VS2005, voici le shcéma :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Fille;
    
    class Mere
    {
       friend void Fille::Fonction(); // <-- Erreur C2027: use of undefined type
    };
    
    class Fille : public Mere
    {
    public:
       void Fonction(){}
    };
    Comment régler ce problème?

    Merci d'avance,
    Nicolas

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 90
    Par défaut
    Tu as entendu parler de protected ?

    Heu... Je viens de relire et en fait je ne vois pas pourquoi tu veux qu'une classe fille ne puisse accéder à la classe mère que par une fonction.

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    Je ne crois pas que tu puisse utiliser friend avec une fonction d'une classe fille.

    Il faut en effet que la fonction soit définie avant d'utiliser friend. Pour ça, il faudrait définir la classe fille avant la classe Mère. Mais si la classe Fille hérite de Mère, Mère doit être définie avant Fille. Il y a une inclusion cyclique qui me parait impossible à résoudre.

    Mais bon, est-tu sûr qu'utiliser friend est une bonne solution ?

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 413
    Par défaut
    Le design de mes classes n'est peut-être pas bon mais pour l'instant je préfère ne pas le changer.
    Pour mettre un exemple plus concret (les classes sont bien sur incomplètes) :
    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
    
    class Control;
    
    class Window
    {
       friend void Control::Anchor(int set);      // Pour pouvoir ajouter des listeners
    
    private:
       void AddListeners(Control &set); 
    
    protected:
       HWND _hWnd;
    
    public:
       void Text(string set);
       ...
    };
    
    class Control : public Window
    {
    public:
       void Anchor(int set)
       {
          ...
          wndParent.AddListeners(*this);
       }
    };
    
    class Button : public Control
    {
       ...
    };
    Pour pouvoir créer une propriété Anchor pour la classe Control, je dois enregistrer une liste de Control dans la fenêtre parente (qui va parcourir la liste lors d'un WM_SIZE).
    Mais je n'ai pas envie de mettre la methode AddListeners en public car elle ne doit pas être utilisable par l'utilisateur qui utiliserait la classe Window.
    Si je la met en protected et que je dérive en public, les classes héritants de Control, comme Button, auront accès à AddListeners, ce qui ne convient pas.
    Si je la met en protected et que je dérive en protected ou private, les utilisateurs finaux n'auront plus accès aux méthodes publiques de Window, comme ici la méthode Text.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 90
    Par défaut
    Est-ce que quelque chose comme ça te conviendrait :
    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
     
    class Mere
    {
    public:
    	void f1() {}
    };
     
    class Mere_: virtual public Mere {
    public:
    	void f2() {}
    };
     
    class Fille1 : virtual public Mere, private Mere_ {
    public:
      void g1() { f2(); }
    };
     
    class Fille2 : public Fille1 {
    public:
      void g2() {
    		//f2(); // inaccessible
    		f1();
    	}
    };

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 413
    Par défaut
    Wow, je n'ai encore jamais dérivé une classe en virtual, je ne savais mm pas qu'il y avait moyen

    Il semblerait que ca puisse convenir à mon cas, par contre je n'ai aucune idée de ce que donne une classe dérivée en virtual ...

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 90
    Par défaut
    Autre solution plus simple : ta fonction friend ne doit pas être une fonction membre mais une fonction dont la déclaration n'est accessible qu'aux classes Mère et Fille1 (#include "fonctionfriend.h" dans "Mere.cpp" et "Fille1.cpp").

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 413
    Par défaut
    Même si elle a l'air moins propre (quoique ca depend pour qui ) je pense que la 2ème solution va me convenir.

    Sinon il y a aussi comme possibilité :
    • Déclarer toute la classe Fille en friend
    • Créer une classe avant la classe Mere qui être friend de Mere et qui sera utilisée par la classe Fille.


    Merci à tous,
    Je pense que je vais utiliser la fonction dont la déclaration n'est accessible qu'aux classes Mere et Fille

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 90
    Par défaut
    Juste pour info, il est possible de déclarer une classe fille avec une fonction friend de la classe mère :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    template<typename T> struct Mere
    {
    	void f() {}
    	friend void T::g();
    };
     
    struct Fille : public Mere<Fille> {
    	void g() {}
    };
    Problème : le compilateur ne peut pas compiler g() si elle accède à Mère

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 90
    Par défaut
    Peut-être ceci est-il plus raisonnable :
    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 Mere {
    public:
    	void f1() {}
    };
     
    class MereInterface {
    public:
    	MereInterface(Mere& mere): mere(mere) {}
    	void f2() {
    		mere.f1();
    	}
    private:
    	Mere& mere;
    };
     
    class Fille1: public MereInterface, private Mere {
    public:
    	Fille1(): MereInterface(*static_cast<Mere *>(this)) {}
    	void f3() { f1(); }
    };
     
    class Fille2: public Fille1 {
    public:
    	void f4() {
    		//f1(); // inaccessible
    		//mere.f1(); // inaccessible
    		f2();
    	}
    };

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 413
    Par défaut
    Je dois t'avouer que j'ai du mal à saisir toute la structure
    Enfin je regarderai ca a tête reposée.

    Merci pour ton aide

  12. #12
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Fille1(): MereInterface(*static_cast<Mere *>(this)) {}
    Les casts c'est suffisamment mal pour qu'on évite d'en mettre quand on n'en a pas besoin
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Fille1(): MereInterface(*this) {}

  13. #13
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 90
    Par défaut
    Citation Envoyé par loufoque
    Les casts c'est suffisamment mal pour qu'on évite d'en mettre quand on n'en a pas besoin
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Fille1(): MereInterface(*this) {}
    Mon compilateur n'est pas d'accord, mais j'ai g++ 3.4.2 ; peut-être est-ce différent avec les nouvelles versions ?

  14. #14
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Le constructeur de MereInterface veut un Mere&, *this est un Fille1 qui hérite de Mere alors il me semble que cela devrait être converti de manière implicite.

  15. #15
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 90
    Par défaut
    Il y a une ambiguité entre MereInterface(Mere&) et MereInterface(const MereInterface&), ce dernier étant le constructeur de copie implicite (ISO 12.8.4).

  16. #16
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Ah oui en effet.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] Limite d'une fonction
    Par Hayabusa dans le forum MATLAB
    Réponses: 2
    Dernier message: 10/03/2010, 19h22
  2. valeur limite d'une fonction
    Par zizo08 dans le forum MATLAB
    Réponses: 20
    Dernier message: 30/11/2008, 16h51
  3. Réponses: 1
    Dernier message: 10/05/2008, 23h36
  4. Impossible d'exécuter d'une fonction
    Par djamila dans le forum MATLAB
    Réponses: 2
    Dernier message: 12/12/2007, 14h55
  5. Réponses: 7
    Dernier message: 20/03/2005, 14h53

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