Bonjour à tous. Bien qu'ayant l'habitude de développer, en particulier de l'objet, je début avec la syntaxe C++ donc je viens vous demander de l'aide pour un projet
Le but est d'arriver à lire des instances de classes décrites en XML sous la forme :
Les classes y sont décrites "à plat". Comme dans mon exemple, si classe B est une classe dérivée de C, et C une classe dérivée de E, les attributs de certaines classes mères sont définis au niveau des classes filles (ces classes sont considérées "abstraites" et sont connues).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 <classA ID="ID_A"> <classA.attr1>value1</classA.attr1> <classA.attr2>value2</classA.attr2> </classA> <classB ID="ID_B"> <classB.attr1>value1</classB.attr1> <classC.attr1>value3</classC.attr1> <classE.attr4>value4</classE.attr4> <classG ID = "ID_G" /> </classB> ...
Les "ID" servent de référence au sein du fichier pour décrire les associations entre les classes.
Par ailleurs, le modèle global de données est bien spécifié (classes, attributs, associations possibles) Ainsi j'ai pour l'instant dans mon modèle de données C++ l'ensemble des classes existantes, avec leurs attributs (et associations). Par exemple donc :
L'objectif est donc d'être capable de lire d'énormes (plusieurs dizaines voire centaines de Mo) de ces fichiers XML pour peupler le modèle de données. L'aspect performance est donc à considérer au niveau du parser. (Bien entendu, SAX sera utilisé, mais moins il y a de calculs et surtout de redondance et meilleur ce sera
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 class classB : public classC{ public : int attr1; }). Le temps de compilation est lui indifférent.
Pour faciliter le développement à venir, toutes ces classes héritent directement ou indirectement d'une classe que l'on appellera "Object" (oui je viens du monde Java)
A noter également qu'aucune vérification du fichier XML n'a besoin d'être effectuée. Ces fichiers sont considérés parfaitement valides et donc les références présentes existent bien, ainsi que l'ensemble des classes et attributs associés ou encore les valeurs littérales indiquées.
La première étape consiste donc à instancier une classe à partir son nom.
Une deuxième étape sera de "setter" l'attribut de la classe, ou d'une de ces ancêtres. S'il s'agit d'une association l'ID de la classe associée est indiquée et on peut alors supposer que garder une map des objets crées est judicieux (id -> Object* par exemple). Si l'objet associé n'a pas encore été créé, il faudra le créer sans rien setter : il sera défini plus tard dans le fichier.
Ainsi la première étape consiste en fait à récupérer l'instance si elle existe, et à la créer sinon.
Pour réaliser les fonctions adéquates, j'imagine qu'il me faut faire appel aux "templates" et "typename". De plus je compte créer une map initialisée au lancement du programme associant le nom d'une classe à son constructeur pour gérer les instanciations sans avoir à parcourir une bonne centaine de "if" sur le nom lu de classe (dans un souci de performance puisque les fichiers sont assez volumineux ...) et je pensais donc à une classe du genre (pardonnez moi, c'est un brouillon dans lequel je zappe les includes et je mets tout en public dans un même fichier source ...) :
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 class Model{ public : map<string, Object*(*)(string)> name_ctor //map (nom -> constructeur) map<string, Object*> name_object // map (id -> instance) Object currentObject // object que l'on est en train de setter Model(){ // créer la map name_ctor : comment faire ? // Je me doute qu'il faut écrire X fois la "même" ligne, mais c'est la partie "valeur" de la map qui me bloque, celle qui pointe vers une fonction } template<typename T> createInstance(string name, string id){ // comment l'écrire ? Il faut vérifier l'existence et effectivement créer si besoin } // Il manque des fonctions pour que tout fonctionne bien ... Help :p void readAttribute(string motherClass, string attribute, string value){ // Chaque "Object" implémente sa fonction "read(string, string, string)" // Utiliser le mot-clé "virtual" dans les classes mères "abstraites" ?? currentObject.read(string motherClass, string attribute, string value); } } class classB : public classC{ public : int attr1; void read(string motherClass, string attribute, string value){ //(il n'y a pas énormément d'attribut, donc un "if then else" est envisageable // une map serait mieux, mais je peine un peu ... if(strcmp(attribute, "attr1")){ // setter } else if ... ... else{ // classC fera la même chose ... // Gérer le "motherClass" serait plus judicieux mais je peine encore ... classC::read(motherClass, attribute, value); } } }
Voilà en gros pour mon code à trous donc si quelqu'un peut m'aider à déblayer tout ça ... J'ai un peu de mal à voir comment faire pour obtenir un code propre et optimisé en fonction des possibilités qu'offre C++.
Merci![]()
Partager