Bonjour à tous
J'ai codé une lib statique de calcul scientifique spécifique à mes travaux (aucune lib là dessus ne préexistait a priori car mon projet est très spécifique à mon application).
Je ne vais pas entrer dans les détails, mais cette lib est constituée de plusieurs classes dont une classe A_ qui est abstraite, ie avec des méthodes déclarées sous la forme virtual (...) = 0 ; . Par ailleurs, toujours dans cette lib, j'ai une autre classe C dont un membre est un pointeur sur A_ (genre A_ *ptrA_). Des fonctions membres de C appellent des méthodes virtuelles pures de A_ via le pointeurs (les appels sont codés ptrA_ -> MethodeAbstraite(...) . Je précise que le ptrA_ pointe sur un espace alloué dynamiquement dans le constructeur de C via un "clone pattern" appliqué sur un objet dérivé de A_, passé en argument dans le constructeur de C... Voir le code pour comprendre ce que je veux dire.
Lorsque je veux utiliser les fonctionnalités de ma lib, je dois donc déclarer une classe B, dérivée de A_ afin de spécifier les méthodes qui sont virtuelles pures ... L'avantage de ce procédé est que j'utilise l'héritage et que surtout, c'est très simple à utiliser car le code de calcul s'adapte à n'importe quel type dérivé de A_ ... suffit juste de définir les quelques méthode virtuelles pures. Cette façon de faire s'avère très pratique pour monter des projets où plusieurs personnes sont impliquées.
Voici un exemple minimum pour illustrer ma description
Voici ce que j'ai codé dans ma lib :
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 // Classe abstraite class A_ { public: virtual double F() const = 0; virtual A_* Clone() const = 0; // + d'autres méthodes virtuelles pures // + des méthodes non virtuelles // des membres }; class C { // Une classe qui contient un pointeur de type A_* public: // Constructeur C(A_* ptrObjectDerive) { ptrA_ = ptrObjetDerive.Clone(); // Appelle le ctr de recopie et alloue dynamiquement la mémoire pointée par ptrA_ // etc ... } void Fonction() { //Une fonction qui appelle ptrA_->F() plus de 100000 fois ... } protected: A_ *ptrA_; double x; //etc... };
Lorsque je veux utiliser ma lib je dois faire cela :
Le prog principal :
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 // Classe dérivée de A_ class B:public A_ { // définition du constructeur, du constructeur de recopie etc... // [....] // Le clone pattern virtual A_* Clone() const { return new A_(*this); } virtual double F () const { // Spécialisation de F ici ... } };
Ma lib fonctionne correctement, mais j'ai lu que travailler avec des virtual était gourmand en temps car la détermination de la méthode à appeler est résolu non pas à la compilation mais à l'exécution. Dans ma situation, j'appelle une méthode virtual des centaines de milliers de fois ... donc quelque chose me dit qu'il est possible de faire un truc bien + performant ... De plus, comme l'atteste le programme principal, on sait dès la compilation quelle fonction F() devra être utilisée, donc il est inutile d'attendre l'exécution pour savoir si je dois appeler telle ou telle méthode membre F. Donc je me dis qu'il y a un sacré manque à gagner ... non ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 // main.cpp // etc... B ObjetB(...) // Création d'un objet B C ObjetC(&ObjetB, ...) //Création d'un objet C ayant un objet de type pointeur_sur_B en paramètre (+ d'autres paramètres) ObjetC.Fonction(); // fonction qui va appeler 100000 fois une méthode codée en virtual
D'où ma question : Est-il possible de re-concevoir autrement le pb tout en gardant cette souplesse d'utilisation (juste spécifier quelques fonctions tout en puissant utiliser ce qui est déjà codé dans la classe abstraite A_) ? Et aussi, en n'utilisant pas de virtual ? Je viens de lire quelques tutos sur la méta programmation avec les 'template' qui cherche à faire bosser le compilateur avant tout ... ça me parait vraiment très intéressant pour mon pb où la rapidité est critique, non ? Sauriez-vous m'aiguiller vers une approche adéquate ?
Merci à vous
Partager