Je suis récemment revenu au développement C++ après un hiatus et j'ai une question concernant l'implémentation du modèle de conception d'état. J'utilise le motif de vanille, exactement comme par le livre du GoF.Résolution d'un problème de déclaration anticipée impliquant une machine d'état en C++
Mon problème est que la machine d'état elle-même est basée sur du matériel utilisé dans le cadre d'un système embarqué - la conception est donc fixe et ne peut pas être modifiée. Cela se traduit par une dépendance circulaire entre deux des états (en particulier), et j'essaye de résoudre ce problème . Voici le code simplifié (notez que j'ai essayé de résoudre ce problème en utilisant têtes comme d'habitude, mais encore eu des problèmes - je les ai omis dans cet extrait de code):
#include <iostream>
#include <memory>
using namespace std;
class Context
{
public:
friend class State;
Context() { }
private:
State* m_state;
};
class State
{
public:
State() { }
virtual void Trigger1() = 0;
virtual void Trigger2() = 0;
};
class LLT : public State
{
public:
LLT() { }
void Trigger1() { new DH(); }
void Trigger2() { new DL(); }
};
class ALL : public State
{
public:
ALL() { }
void Trigger1() { new LLT(); }
void Trigger2() { new DH(); }
};
// DL needs to 'know' about DH.
class DL : public State
{
public:
DL() { }
void Trigger1() { new ALL(); }
void Trigger2() { new DH(); }
};
class HLT : public State
{
public:
HLT() { }
void Trigger1() { new DH(); }
void Trigger2() { new DL(); }
};
class AHL : public State
{
public:
AHL() { }
void Trigger1() { new DH(); }
void Trigger2() { new HLT(); }
};
// DH needs to 'know' about DL.
class DH : public State
{
public:
DH() { }
void Trigger1() { new AHL(); }
void Trigger2() { new DL(); }
};
int main()
{
auto_ptr<LLT> llt (new LLT);
auto_ptr<ALL> all (new ALL);
auto_ptr<DL> dl (new DL);
auto_ptr<HLT> hlt (new HLT);
auto_ptr<AHL> ahl (new AHL);
auto_ptr<DH> dh (new DH);
return 0;
}
Le problème est essentiellement que dans le modèle d'État , les transitions d'état sont effectuées par en invoquant la méthode ChangeState dans la classe Context, qui appelle le constructeur de l'état suivant.
En raison de la dépendance circulaire, je ne peux pas invoquer le constructeur car il est impossible de prédéfinir les deux constructeurs des états 'problème'.
J'ai regardé this article, et la méthode de modèle qui semblait être la solution idéale - mais il ne compile pas et ma connaissance des modèles est un peu limité ...
L'autre idée que je Il faut essayer d'introduire une classe Helper dans les états sous-classes, via l'héritage multiple, pour voir s'il est possible de spécifier le constructeur de la classe de base et de faire référence au constructeur de la sous-classe d'état. Mais je pense que c'était plutôt ambitieux ...
Enfin, une implémentation directe du modèle de conception de méthode d'usine serait-elle la meilleure façon de résoudre le problème entier?
Salut James! Beaucoup, beaucoup merci en effet pour la réponse rapide - qui fonctionne parfaitement :-) Excuses, j'ai oublié de mettre les suppressions correspondantes dans chacun des nouveaux appels() dans l'extrait de code. – HypersonicNinja
@hyper: Pas de problème; Je voulais juste m'assurer que ce n'était pas la seule chose dans tes fonctions ... :-) –