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 abstraite et methode static de factory


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    208
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 208
    Par défaut Classe abstraite et methode static de factory
    Bonjour,

    J'aimerai créer une classe abstraite A et deux classe dérivante AA et AB
    Je veux que la classe A contienne une méthode static pour la création des objets de type AA et AB et une méthode virtuel implémenté dans AA et AB

    J'ai donc le code suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class A
    {
    public:
    	static A Create(BOOL bIsB = false);
    	~A(void);
    protected:
    	A(void);
    	virtual void Run()=0;
    };
    Pour AA et AB
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class AA :
    	public A
    {
    public:
    	AA(void);
    	~AA(void);
    	virtual void Run();
    };

    Pour la méthode Create j'ai:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    A A::Create(BOOL bIsB)
    {
    	if(bIsB)
    		return AB();
    	else
    		return AA();
    }

    Et à la compilation j'ai une erreur : error C2259: 'A'*: impossible d'instancier une classe abstraite


    J'ai loupé quelque chose???

    Merci pour vos lumières

  2. #2
    Membre chevronné

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Par défaut
    Salut,
    J'ai loupé quelque chose???
    Oui en effet! La classe A est une classe abstraite (c'est même toi qui le dit ) alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    static A Create(BOOL bIsB = false);
    ...
    A A::Create(BOOL bIsB)
    n'est pas correct, car 'Create' renvoie un objet de la classe A : Comme A est une classe abstraite, on ne peut pas créer d'objets de cette classe. C'est d’ailleurs ce que dit ton message d'erreur.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    208
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 208
    Par défaut
    Oui mais je crée pas réellement un objet de type A, je crée un objet de type AB ou AA et je renvoie un objet de type A.

    En c#, cela est possible. Masi en C++ je dois apparemment renvoyé un pointeur de A :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    A* A::Create(BOOL bIsB)
    {
    	if(bIsB)
    		return new AB();
    	else
    		return new AA();
    }

  4. #4
    Membre chevronné

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    je crée un objet de type AB ou AA et je renvoie un objet de type A.
    Non, non et non on ne peut pas!!!

    Les AA et les AB tu en instancie tant que tu veux, mais pour les A ce n'est pas possible, ou sinon, il faut que A ne soit pas abstraite

    De plus, si A n'était pas abstraite, tu pourrais être confronté au problème de 'slicing' développé ici

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    208
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 208
    Par défaut
    Citation Envoyé par bertry Voir le message
    Les AA et les AB tu en instancie tant que tu veux, mais pour les A ce n'est pas possible
    Argf, justement je n'instancie pas de A: tu as vu ça où???

  6. #6
    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,
    Citation Envoyé par Troopers Voir le message
    Argf, justement je n'instancie pas de A: tu as vu ça où???
    Mais si, justement...

    Comme tu ne renvoie ni un pointeur ni une référence, ce que tu renvoie est... une instance de type A (et non de type AA ou de type AB), ce qui est strictement interdit...

    Pour que cela fonctionne, et pour profiter du polymorphisme au passage, tu dois renvoyer une référence ou un pointeur sur un objet "passant pour être" de type A.

    Tu dois, en outre, faire attention au fait que l'objet référencé ne soit pas détruit au moment de sortir de la fonction, si tu décide de renvoyer une référence.

    La signature de ta fonction doit donc être de l'ordre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class A
    {
    public:
    	static A& Create(BOOL bIsB = false);
    };
    ou de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class A
    {
    public:
    	static A Create(BOOL bIsB = false);
    };
    et son implémentation proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    A* A::Create(BOOL bIsB)
    {
    	if(bIsB)
    		return new AB();
    	else
    		return new AA();
    }
    ou, si cela a un sens, t'orienter vers quelque chose de proche 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
    class A
    {
    public:
        static A& Create(BOOL bIsB = false)
        {
            if(! m_member)
            {
                if(bIsB)
                    m_member = new AB();
                else
                   m_member = new AA();
                }
            return *m_member;
        }
        private:
        A* m_member;
    };
    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

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

Discussions similaires

  1. [POO] classe abstraite sans methode
    Par ZaaN dans le forum C++
    Réponses: 7
    Dernier message: 01/05/2007, 19h21
  2. Classe interne, methode static et ajout de boutons
    Par comme de bien entendu dans le forum AWT/Swing
    Réponses: 6
    Dernier message: 09/03/2006, 14h13
  3. [POO] class abstraite et methode magic
    Par jeff_! dans le forum Langage
    Réponses: 14
    Dernier message: 24/01/2006, 23h19
  4. Réponses: 13
    Dernier message: 15/11/2005, 15h47
  5. Réponses: 6
    Dernier message: 27/07/2005, 09h06

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