Bonjour,
Comme je ne suis pas encore un pro des templates, j’aimerais juste une petite validation de votre part.
j'ai donc fait un template pour autovalider des objets dans une bibliothèque ...
le principe est simple, ils sont enregistré dans une classe Referencies, dans une liste sur leurs interface de base et je peux les instancier
voici mes codes
code des classe exemple
code du template
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 #pragma region CLASS DE BASE class Base { public: virtual void execute() = 0; }; class A{ public: A(){ cout << " creation A " << endl; } ~A(){ cout << " destruction A " << endl; } virtual void execute(){ } }; class B{ public: virtual void execute(){ } }; class C{ }; //A a; //B b; #pragma endregion
code d’utilisation
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
59
60
61
62
63
64 //------------------------------------------------------------------------------- #pragma region REFERENCE ET ADDREFERENCE class baseConstructor { public: virtual void *create() = 0; }; template<typename Type> class constructor : public baseConstructor{ public: virtual void *create(){ return new Type(); } }; /* Class static de references */ template<class Interface> class Referencies { private: Referencies(){} public: static void Add(string className, baseConstructor *c) { if (list == NULL) { list = new map<string, baseConstructor *>(); } cout << " Add referencies " << className << endl; (*list)[className] = c; } static vector<string>* getClass(){ vector<string> *vec = new vector<string>(); for (map<string, baseConstructor *>::iterator it = list->begin(); it != list->end(); ++it) vec->push_back((*it).first); return vec; } static Interface* newInstance(string s){ try{ Interface* i = (Interface*)(*list)[s]->create(); return i; } catch (...){ return NULL; } } private: static map<string, baseConstructor *> *list; }; /* membre static de Referencies */ template<class Interface> map<string, baseConstructor *> *Referencies<Interface>::list = NULL; template<class Interface, class Type> class AddReferency { public: AddReferency(){ cout << "[AddReferency] create " << endl; Referencies<Interface>::Add(type_name<Type>(), new constructor<Type>()); } ~AddReferency(){ cout << "[AddReferency] delete " << endl; } }; #pragma endregion
code d'utilitaires
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 // usage en static AddReferency<Base, A> insert; AddReferency<Base, B> insert1; AddReferency<B, A> insert2; // utilisation show(Referencies<Base>::getClass()); cout << "referebnce sur bn " << endl; show(Referencies<B>::getClass()); Base *b = Referencies<Base>::newInstance("A");
voila vous pouvez commenter mon code, si on peut l’écrire mieux notamment au niveau du constructeur constructor etc...
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 // code pour remplacer le typeid(T).name() std::string replace(std::string base, const std::string from, const std::string to) { std::string SecureCopy = base; for (size_t start_pos = SecureCopy.find(from); start_pos != std::string::npos; start_pos = SecureCopy.find(from, start_pos)) { SecureCopy.replace(start_pos, from.length(), to); } return SecureCopy; } bool my_predicate(char c) { return (c >= 0x30 && c < 0x39); } #include <algorithm> template<typename T> string type_name(){ string s = string(typeid(T).name()); // for visual c++ s = replace(s, string("class"), string("")); s = replace(s, string(" "), string("")); // for gcc s.erase(std::remove_if(s.begin(), s.end(), my_predicate), s.end()); cout << s << endl; return s; } // visualisation des entrées void show(vector<string> *list){ cout << endl << "LIST " << endl; for (vector<string>::iterator it = list->begin(); it != list->end(); ++it) { cout << " -" << (*it) << endl; } }
Partager