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 :

Classe amie d'une classe abstraite


Sujet :

C++

  1. #1
    Membre du Club Avatar de trecks
    Étudiant
    Inscrit en
    Janvier 2007
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 91
    Points : 58
    Points
    58
    Par défaut Classe amie d'une classe abstraite
    Bonjour à tous

    Est ce qu'une classe peut etre amie d'une classe abstraite?
    Quels est le meilleur ami de l'homme ?
    Hum un compilateur C++ bien sûr

  2. #2
    Alp
    Alp est déconnecté
    Expert éminent sénior

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Il me semble oui. Je vois pas pourquoi ça ne serait pas bon.
    Cependant l'intérêt en serait limité.

    Ca gâche le polymorphisme. Tu peux expliquer le contexte succintement ?

  3. #3
    Membre actif Avatar de Chen norris
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2004
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Mai 2004
    Messages : 216
    Points : 248
    Points
    248
    Par défaut
    J'imagine que c'est pour obtenir une classe amie de toutes les classe dérivées... ?
    Chen norris
    C/C++, C#, Java, PHP & SQL coder
    Web developer

  4. #4
    Alp
    Alp est déconnecté
    Expert éminent sénior

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Bah ça ne marchera pas. Une classe A est amie de B, pas de ses filles, si je ne m'abuse.

  5. #5
    Alp
    Alp est déconnecté
    Expert éminent sénior

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Au temps pour moi, j'ai eu tord...
    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
    #include <iostream>
     
    using namespace std;
    class C;
    class B;
     
    class A
    {
    	friend class B;
    	int a;
     
    	public:
    	virtual void f() = 0;
    };
     
    class C : public A
    {
    	public:
    	void f() { }
    };
     
    class B
    {
    	C inst;
    	public:
    	void f(int n)
    	{
    		inst.a = n;
    		cout << inst.a << endl;
    	}
    };
     
     
    int main()
    {
    	B b;
    	b.f(1);
    	return 0;
    }
    Aucun problème avec ce code...

  6. #6
    Membre du Club Avatar de trecks
    Étudiant
    Inscrit en
    Janvier 2007
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 91
    Points : 58
    Points
    58
    Par défaut
    Et bien en fait j'ai plusieurs classe manager : CSpriteManager qui affiche les sprite, CCameraManager qui gère les différentes caméra, CTextureManager pour les textures, et toutes ces classes ont une méthodes Render(laFenetreCible) : ces manager héritent tous de IManagerRenderer qui possède une méthode virtuelle pure Render(laFenetreCible).
    Cependant ce n'est pas à l'utilisateur d'appeller chacune de ces méthodes, parce si j'ai 10 manager comme ceux la ça devient vite fastidieux donc j'ai mis ces méthodes en privées.
    J'ai ensuite créé une classe CRenderer qui va se charger d'appeller les méthodes Render de tous ces managers à la place de l'utilisateur. Cette classe contient un vecteur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::vector<IManagerRenderer*> m_vManager;
    Puis elle contient aussi une méthode RenderToScreen(laFenetreCible)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void CRenderer::Render(sf::RenderWindow *pWindow)
    {
    	for(m_vManagerIter = m_vManager.begin(); m_vManagerIter != m_vManager.end(); ++m_vManagerIter)
    		(*m_vManagerIter)->Render(pWindow);
    }
    Mais comme vous le voyez cette méthode doit accéder aux méthodes Render de chaque manager (qui sont aussi de type IManagerRender puisqu'ils en héritent) qui sont en privées (pour ne pas que l'utilisateur y accède). Donc pour que mon CRenderer accède à ces méthodes privées, je souhaite qu'il soit ami de IManagerRender pour accéder à la méthode Render de cette classe et donc à toutes les méthodes Render de tous les managers qui héritent de IManagerRender.

    J'espère avoir était clair, mais c'est pas facile à expliquer^^
    Quels est le meilleur ami de l'homme ?
    Hum un compilateur C++ bien sûr

  7. #7
    Alp
    Alp est déconnecté
    Expert éminent sénior

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Visiblement ça ne pose aucun problème, l'amitié est préservée lors de l'héritage, mais pour ce qui est présent dans la classe mère seulement, normalement.

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Oui, si on déclarait une fonction x() dans la classe C, B ne pourrait pas l'appeler.
    Néanmoins, comme beaucoup d'autre je n'aime pas les classes amies. En général, je considère qu'une méthode est la pour une bonne raison et est donc utilisable à loisir, donc en public. Pour moi, les méthodes private ne sont la que pour partitionner un algo complexe ou pour interdire explicitement certaines choses (la copie par exemple).
    Les seuls cas où je pourrais interdire l'utilisation de quoi que ce soit sont ceux où j'ai des classes à usage interne qui ne sont d'aucune utilité à l'utilisateur, mais dans ces cas la je les déclare généralement dans un namespace supplémentaire style "detail" ou "others".

  9. #9
    Alp
    Alp est déconnecté
    Expert éminent sénior

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    J'ai pris l'habitude d'avoir un namespace privé pour y déclarer tout ce qui fait tourner mon code mais qui n'a pas lieu d'être accessible par l'utilisateur.

    PS : je ne suis pas partisan de l'utilisation de l'amitié, non plus.

  10. #10
    Membre du Club Avatar de trecks
    Étudiant
    Inscrit en
    Janvier 2007
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 91
    Points : 58
    Points
    58
    Par défaut
    Mais ou est l'erreur?

    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
     
    #ifndef __IManagerRender_h__
    #define __IManagerRender_h__
     
    #include <iostream>
    #include <SFML/Graphics.hpp>
    #include "CRenderer.h"
     
    namespace SLE
    {
    	class IManagerRender
    	{
    		friend class CRenderer;
     
    	public:
    		IManagerRender(){}
    		virtual ~IManagerRender(){}
     
    	private:
    		virtual void Render(sf::RenderWindow *pWindow) = 0;
    	};
    }
     
    #endif
    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
     
    #ifndef __CRenderer_h__
    #define __CRenderer_h__
     
    #include <iostream>
    #include <vector>
    #include <SFML/Graphics.hpp>
    #include "CSingleton.h"
     
    namespace SLE
    {
    	class IManagerRender;
    	class CRenderer : public CSingleton<CRenderer>
    	{
    		friend class CSingleton<CRenderer>;
    	public:
    		//Enregistre un manager en tant que manager de rendu
    		void RegisterManagerToRendering(IManagerRender *pManager);
     
    		//Rendu de la scène
    		void RenderScene(sf::RenderWindow *pWindow);
     
    	private:
    		CRenderer();
    		virtual ~CRenderer();
     
    		typedef std::vector<IManagerRender*> m_Vector;
    		m_Vector m_vManager;	//Vecteur des managers de rendu
    		m_Vector::iterator m_vManagerIter;	//Itérateur de parcours du vecteur
    	};
    }
     
    #endif
    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
     
    #include "CRenderer.h"
     
    using namespace SLE;
     
    CRenderer::CRenderer()
    {}
     
    CRenderer::~CRenderer()
    {
    	m_vManager.clear();
    }
     
    void CRenderer::RegisterManagerToRendering(IManagerRender *pManager)
    {
    	if(pManager)
    		m_vManager.push_back(pManager);
    }
     
    void CRenderer::RenderScene(sf::RenderWindow *pWindow)
    {
    	for(m_vManagerIter = m_vManager.begin(); m_vManagerIter != m_vManager.end(); ++m_vManagerIter)
    		(*m_vManagerIter)->Render(pWindow);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    1>c:\documents and settings\admin\bureau\projet sle - plateforme\sle\sle\crenderer.cpp(22) : error C2027: utilisation du type non défini 'SLE::IManagerRender'
    1>        c:\documents and settings\admin\bureau\projet sle - plateforme\sle\sle\crenderer.h(11) : voir la déclaration de 'SLE::IManagerRender'
    1>c:\documents and settings\admin\bureau\projet sle - plateforme\sle\sle\crenderer.cpp(22) : error C2227: la partie gauche de '->Render' doit pointer vers un type class/struct/union/générique
    Quels est le meilleur ami de l'homme ?
    Hum un compilateur C++ bien sûr

  11. #11
    Alp
    Alp est déconnecté
    Expert éminent sénior

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    ImageRender.h n'est jamais inclus.
    Alors quand tu t'en sers dans crenderer.cpp, il se demande de quoi tu causes

  12. #12
    Membre du Club Avatar de trecks
    Étudiant
    Inscrit en
    Janvier 2007
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 91
    Points : 58
    Points
    58
    Par défaut
    Ce n'est pas ImageRender mais IManagerRender ^^ lol mais c'est pas le problème, il est bien inclus juste après la déclaration du namespace

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    namespace SLE
    {
         class IManagerRender;
         class CRenderer
         {
              ...
         };
    }
    Quels est le meilleur ami de l'homme ?
    Hum un compilateur C++ bien sûr

  13. #13
    Alp
    Alp est déconnecté
    Expert éminent sénior

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Non il n'est pas inclus. Là c'est une déclaration anticipée.
    Dans crenderer.cpp, tu dois inclure le fichier d'en-tête de IManagerRender.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #include "imanagerrender.h"
    par exemple.

  14. #14
    Membre du Club Avatar de trecks
    Étudiant
    Inscrit en
    Janvier 2007
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 91
    Points : 58
    Points
    58
    Par défaut
    Oué ca marche bien Alp, merci à vous tous et vive developpez.com^^
    Quels est le meilleur ami de l'homme ?
    Hum un compilateur C++ bien sûr

  15. #15
    Alp
    Alp est déconnecté
    Expert éminent sénior

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Citation Envoyé par trecks Voir le message
    Oué ca marche bien Alp, merci à vous tous et vive developpez.com^^
    Tu l'as dit

  16. #16
    Membre du Club Avatar de trecks
    Étudiant
    Inscrit en
    Janvier 2007
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 91
    Points : 58
    Points
    58
    Par défaut
    Mais à quoi ça sert de mettre class IManagerRender alors que l'on inclus IManagerRender.h parce si j'enlève class IManagerRender mon compilateur me sort environ 300 erreurs
    Quels est le meilleur ami de l'homme ?
    Hum un compilateur C++ bien sûr

  17. #17
    Alp
    Alp est déconnecté
    Expert éminent sénior

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Tu mets
    dans crenderer.h
    Cela signifie, en gros : "il existe une classe IManagerRender mais elle est définie soit plus loin dans ce fichier soit dans un autre fichier". Cela ne donne aucun détail sur les fonctions membres et attributs, entre autres.

    Dans ton .cpp, tu as besoin de connaître les fonctions membres publiques de cette classe car tu les appelles! Il faut connaître donc leur prototype par exemple. Et ces informations, on les a lorsque l'on inclut le fichier d'en-tête de IManagerRender.

  18. #18
    Membre du Club Avatar de trecks
    Étudiant
    Inscrit en
    Janvier 2007
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 91
    Points : 58
    Points
    58
    Par défaut
    ok merci beaucoup Alp et tous les autres bien sûr ^^
    Quels est le meilleur ami de l'homme ?
    Hum un compilateur C++ bien sûr

  19. #19
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Citation Envoyé par Alp Voir le message
    ... l'amitié est préservée lors de l'héritage, mais pour ce qui est présent dans la classe mère seulement, normalement.
    Ta phrase reste assez floue et ambigue. Un petit rappel : http://cpp.developpez.com/faq/cpp/?p...RIEND_heritage

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 18/09/2012, 14h58
  2. Réponses: 3
    Dernier message: 14/07/2012, 19h39
  3. Réponses: 2
    Dernier message: 02/02/2008, 07h37
  4. Réponses: 8
    Dernier message: 20/07/2007, 14h28
  5. fonction membre d'une classe amie d'une autre classe
    Par olive_le_malin dans le forum C++
    Réponses: 3
    Dernier message: 16/11/2006, 09h39

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