Pour l'instant peu importe. C'est pas le problème. Mais on peut parfaitement utiliser des références vers le message d'origine. D'ailleurs c'est ce que je fais dans mon code chez moi.
Il ne demande pas pourquoi tu passes des vector<string>, il demande pourquoi tu les passes par valeur.
oui je m'en suis aperçu après avoir écris le premier message. Woa zet rapides à répondre![]()
Bon ça compile enfin. Je n'ai pas encore vérifié le comportement au niveau des classes filles de ServerCom mais ça devrait bien se passer.
Allez j'envoie le code !
D'abord je décris les classes de commandes qui vont être utilisées par ma fabrique de commande. Je me suis largement inspiré du code présent sur cette page http://sourcemaking.com/design_patterns/command/c++/3 qui implémente le pattern Commande sur des fonctions membres.
Maintenant ma fabrique de commandes :
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 class Command { public: virtual bool execute(std::vector<std::string>&) = 0; }; template <class T> class Prototype { public: virtual ~Prototype() {} virtual T* clone() const = 0; }; //J'ai voulu faire propre en écrivant les classes Command et Prototype à part //Mais on peut directement créer la classe CmdPrototype class CmdPrototype : public Command, Prototype<CmdPrototype> { public: virtual bool execute(std::vector<std::string>& params) = 0; virtual CmdPrototype* clone() const = 0; }; //J'utilise un template pour faire accepter des fonctions membres de classes filles de ServerCom //Ca peut surement être amélioré template<typename T> class ActionCmd : public CmdPrototype { private: typedef bool (T::*Action)(std::vector<std::string>&); T* receiver; Action action; public: ActionCmd(T* rec, Action act); bool execute(std::vector<std::string>& params); CmdPrototype* clone() const; }; template<typename T> ActionCmd<T>::ActionCmd(T* rec, Action act) { receiver = rec; action = act; } template<typename T> bool ActionCmd<T>::execute(std::vector<std::string>& params) { return (receiver->*act)(params); } template<typename T> CmdPrototype* ActionCmd<T>::clone() const { return new ActionCmd(*this); }
Plus qu'à insérer cette fabrique dans ma classe ServerCom :
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 class CmdFactory { private: std::map<std::string,CmdPrototype*> m_map; public: void add(const std::string& key,CmdPrototype* obj); CmdPrototype* create(const std::string& key) const; }; void CmdFactory::add(const std::string& key,CmdPrototype* obj) { if(m_map.find(key)==m_map.end()) { m_map[key] = obj; } } CmdPrototype* CmdFactory::create(const std::string& key) const { CmdPrototype* tmp= NULL; std::map<string, CmdPrototype*>::const_iterator it=m_map.find(key); if(it!=m_map.end()) { tmp=((*it).second)->clone(); } return tmp; }
J'ai même utilisé des références pour passer mes paramètres...
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
40 class ServerCom : public Server { protected: CmdFactory factory; //lance la fonction de traitement 1 avec des paramètres sous forme de chaine de caractères bool launchTraitement1(std::vector<std::string>& params) { //Si params corrects //lancer fonction_de_traitement1( param1, param2 ...) et retourner true; //Sinon retourner false } bool launchTraitement2(std::vector<std::string>& params) { // ... } // ... void readData(std::string data) { std::vector<std::string> params; std::string command; //parser data et stocker dans params //retirer le premier element de params et le stocker dans command if (!factory.create(command)->execute(params)) { //Traiter l'erreur } } virtual void initFactory() { factory.add("COMMAND1", new ActionCmd<ServerCom>(this, &ServerCom::launchTraitement1)); factory.add("COMMAND2", new ActionCmd<ServerCom>(this, &ServerCom::launchTraitement2)); // ... } public: ServerCom() { initFactory(); } ~ServerCom() {} };
Reste encore à tester ça à l'usage. Si vous avez des remarques, postez.
Je vais continuer à étudier les design patterns. C'est vraiment intéressant. Encore Merci.
Surement juste une erreur de recopie (car ceci ne peut pas passer à la compilation), mais au cas ou je te l'indique quand même :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 template<typename T> bool ActionCmd<T>::execute(std::vector<std::string>& params) { return (receiver->*act)(params); }Parfois, voir même souvent on peut avoir des suprise lors de l'exécution...Envoyé par anoward
Pourtant ça compile chez moi... D'ailleurs cette écriture est utilisée dans le code dont je me suis inspiré. Je laisse le topic ouvert le temps de vérifier si tout se passe bien.
Je dis ça comme ça, mais l'attribut de la classe 'ActionCmd' qui est de type 'Action' se nomme 'action' et non pas 'act', donc ta méthode 'execute()' ne peut pas compiler telle quelle.
Maintenant si tu me dis que ça compile sans erreur, c'est qu'il doit y avoir une faute dans le code posté.
En effet j'avais pas remarqué. Mais ça compile... Quand le c++ rejoint la métaphysique
Je vois pas d'où ça vient pour l'instant. Pas encore eu le temps de tester.
Je vous tiens au courant.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager