Bonjour,
imaginons que nous travaillons sur une bibliothèque. Nous voulons donc, idéalement, exporter un seul en-tête qui propose le protocole (ensemble des fonctions et variables publiques) et cacher l'implémentation en elle même.
Pour ce faire, rien de tel qu'un classique pimpl:
Vous noterez la présence de cette variable membre privée: a_super_important_value. Elle est type int.
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 /***** my_lib.h ********/ class MyLibImpl; class MyLib { public: // protocol void DoSomething(); // ... private: MyLibImpl * pimpl_; // pimpl: tout sera implémenté dans cette classe int a_super_important_value; }; /***** my_lib.cpp ********/ #include "my_lib.h" #include "my_lib_impl.h" void MyLib::DoSomething() { pimpl->DoSomething(); }
Donc imaginons que nous avons implémenté notre lib, que ça marche qu'on est prêt à lancer des tests en pré-prod. Et là, subitement, le commercial nous appelle et nous explique que finalement, cette super_important_value ne sera pas forcément un entier, mais d'un type indéterminé (donc pas forcément natif) que le client doit pouvoir choisir. Les commerciaux sont très forts, et dans cette situation hypothétique, nous nous sommes laissé convaincre, sans même s'en rendre compte, que c'était une bonne idée, et c'était pas bien grave de prévenir alors que le code était finit.
Ok donc, pas de problème, grâce au c++ on peut tout faire. Pour ce problème là, on a les templates. Je vais transformer ma classe en template et ça va rouler tout seul:
Sauf que non, on me fait signe que c'est pas possible! Et pour une raison toute bête: le code d'une classe template doit être dans l'en-tête (ou inclure le cpp à la fin de l'en-tête ce qui revient au même). Et donc ça casse mon pimpl.
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 /***** my_lib.h ********/ class MyLibImpl; template <typename T> class MyLib { public: // protocol void DoSomething(); // ... private: MyLibImpl * impl_; // pimpl: tout sera implémenté dans cette classe T a_super_important_value; };
Savez-vous quelles sont les solutions pour se sortir de cette situation à peu de frais?
Partager