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 :

Problemes avec implementation de decorateurs


Sujet :

C++

  1. #21
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Salut,

    C'est avec plaisir que je donne les quelques informations que j'ai.

    Citation Envoyé par donkeyquote Voir le message
    En fait la methode Clone doit etre virtuelle parce que la factory doit "creer le bon objet".
    C'est vrai, mais c'est un peu court.

    Citation Envoyé par donkeyquote Voir le message
    Mais ce qui me fait chi*r c'est de ne pas pouvoir faire appel de la methode attack() en tant qu'element de type "DecoratorArc" une fois que j'ai fait a posteriori un "wrapper" de type "DecoratorUpgradable".
    Ceci en revanche n'est pas vrai. Si tu conçoit bien ta fonction Clone, tu peux tout à fait faire cela. Heureusement, sinon, il n'y aurait aucun intérêt à utiliser la factory.

    Voici des indices pour te mettre sur la piste : oublions la factory pour le moment et concentrons nous sur les décorateurs. Si tu construit un objet "archer" de la manière dont tu l'as proposé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    WarElement * aWarElement2 = new WarElement(100, 15); // Points of life 100, Power 15 
    aWarElement2 = new DecoratorArc(*aWarElement2, 200, 100); //Points of life upgrade 200 / Power 60
    aWarElement2 = new DecoratorUpgradable(*aWarElement2);
    aWarElement2->lifeUp(0.2); //+20% life up
    aWarElement2->powerUp(0.3); //+30% power up
    et qu'ensuite, tu fais appel à la fonction, par exemple
    Tu t'attend à ce qu'il se produise la chose suivante :
    -> la fonction int DecoratorUpgradable::getLife() est exécutée
    -> elle appelle la fonction int DecoratorArc::getLife()
    -> celle-ci appelle la fonction int WarElement::getLife() qui renvoie 100
    -> DecoratorArc::getLife() n'ajoute rien au résultat et se contente de le renvoyer
    -> DecoratorUpgradable::getLife() ajoute 30% au résultat et le renvoie

    Je suppose que tu as bien compris que chaque fonction d'un décorateur que tu redéfinis est obligée d'appeler la fonction équivalent de l'objet de base.
    Imaginons par exemple que le fait de posséder l'arc fasse perdre deux points de vie à tes unités (par exemple, pour représenter la force qu'elles dépensent à l'utiliser).

    Si tu as définis ta fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int DecoratorUpgradable::getLife()
    comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int DecoratorUpgradable::getLife()
    {
    	return m_Base.m_Life*m_coefficientUpgrade;
    }
    et que tu définis ta fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int DecoratorArc::getLife()
    comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int DecoratorArc::getLife()
    {
    	return m_Base.m_Life-2;
    }
    et bien ton programme ne marchera pas : quand tu appelleras
    , il se produira la chose suivante :
    -> la fonction int DecoratorUpgradable::getLife() est exécutée
    -> elle n'appelle la fonction int DecoratorArc::getLife() elle renvoie directement m_Base (c'est à dire 100) -2, (c'est à dire 98)

    Ce n'est pas ce que tu veux, ce que tu veux, c'est définir tes fonctions comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int DecoratorUpgradable::getLife()
    {
    	return m_Base.getLife()*m_coefficientUpgrade;
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int DecoratorArc::getLife()
    {
    	return m_m_Base.getLife()-2;
    }
    Ainsi tu auras exactement le comportement voulu et
    CODE]aWarElement2.getLife()[/CODE] te renverra bien 100*1.3-2 = 128.

    Je suppose que tu as parfaitement bien compris ceci.
    Et bien maintenant il ne te reste plus qu'à appliquer le même raisonnement à la fonction .

    Une fois que ceci sera fait, c'est à dire une fois que le code suivant fonctionnera :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ...
    	WarElement * aWarElement2 = new WarElement(100, 15); // Points of life 100, Power 15 
    	aWarElement2 = new DecoratorArc(*aWarElement2, 200, 100); //Points of life upgrade 200 / Power 60
    	aWarElement2 = new DecoratorUpgradable(*aWarElement2);
    	aWarElement2->lifeUp(0.2); //+20% life up
    	aWarElement2->powerUp(0.3); //+30% power up
     
    	WarElement * aWarElement1 = aWarElement2.Clone();
     
    	std::cout<<"Points of life of aWarElement1 before attack " <<aWarElement1 ->getTotalPointsOfLife()<<std::endl;
    	aWarElement2->attack(aWarElement1 );		
    	std::cout<<"Points of life of aWarElement1 after attack " <<aWarElement1 ->getTotalPointsOfLife()<<std::endl;
    Ce ne sera plus très dur d'introduire la Factory et de faire fonctionner le code que tu proposes plus haut.

  2. #22
    Membre confirmé Avatar de donkeyquote
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    195
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 195
    Par défaut


    Bon je crois avoir trouve une solution a mes problemes d'implemenation des decorateurs grace aux dernieres super explications de Feriaman.

    J'adjoins le code en esperant que cela pourra servir a d'autres personnes en detresse...

    J'aimerais bien avoir vos commentaires, critiques, remarques, ameliorations, "j'aurais plutot fait comme ca", ... Je crois que cela pourra m'aider a ameliorer ma technique et aprendre de nouvelles choses...

    Merci
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. Probleme avec la copie des surfaces
    Par Black_Daimond dans le forum DirectX
    Réponses: 3
    Dernier message: 09/01/2003, 10h33
  2. Problèmes avec le filtrage des ip
    Par berry dans le forum Réseau
    Réponses: 9
    Dernier message: 30/12/2002, 07h51
  3. probleme avec la touche F10
    Par b.grellee dans le forum Langage
    Réponses: 2
    Dernier message: 15/09/2002, 22h04
  4. Probleme avec fseek
    Par Bjorn dans le forum C
    Réponses: 5
    Dernier message: 04/08/2002, 07h17
  5. [Kylix] probleme avec un imagelist
    Par NicoLinux dans le forum EDI
    Réponses: 4
    Dernier message: 08/06/2002, 23h06

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