J'ai eu l'idée de ce petit exercice en examinant le texte http://www.codeproject.com/KB/cpp/safeGenericPointer.aspx proposé par Francis Xavier sur le Code Project. Je n'ai pas regardé ses sources alors j'ai fait un petit truc dans la même lignée, pour m'amuser, en me disant que ça pourrait intéresser mes étudiant(e)s. L'idée originale, donc, est de lui, pas de moi, mais l'ébauche d'implémentation décrite ici est la mienne. Notez que ceci n'est pas aussi sophistiqué que la technique décrite dans l'article sur l'effacement de types, mais ça peut donner des idées.
Imaginons un programme C++ comme celui décrit à droite. Remarquez le type any_ptr et l'usage qui en est fait :
Nous souhaitons un affichage comme celui ci-dessous lors de l'exécution du programme exemple proposé ici :
Comment pourrions-nous implémenter simplement le type any_ptr? Vous remarquerez qu'un any_ptr dans cet exemple serait un type de pointeur intelligent implémentant une sémantique de référence : il mène vers un pointeur mais n'en est pas responsable. Nous pourrions supporter d'autres pointeurs intelligents dans any_ptr, plutôt que nous limiter à des pointeurs bruts, mais cela compliquerait singulièrement le code. Un exercice pour gens courageux! Notez aussi que nous ne mènerons pas l'entreprise jusqu'au point où nous supporterions les conversions correctes au sens des qualifications const et volatile (ce serait amusant, mais beaucoup plus complexe – vous pouvez vous amuser à le faire si le coeur vous en dit). |
|
Le type any_ptr (ou du moins l'ébauche simplifiée que j'ai pris le temps de rédiger) se décline comme proposé à droite :
|
|
Petit détail : on ne peut utiliser capture() telle qu'elle est écrite sur nullptr et son type, ce qui explique que le pointeur d'un any_ptr par défaut soit non pas nullptr mais bien un void* de valeur 0.
Et voilà!
La classe any_ptr décrite plus bas est une classe légale en C++ 11. Cependant, il est possible d'ajouter quelques outils écrits à la main pour que celle-ci compile sur un compilateur C++ 03 si cela s'avère nécessaire pour vous. Les outils à ajouter reposent prncipalement sur des techniques de métaprogrammation et permettent d'assurer une forme de résilience minimale dans l'implémentation de la classe any_ptr. Ils sont décrits à droite (vous pouvez donc les utiliser si nécessaire) :
L'article sur la métaprogrammation donne plus de détails sur chacune de ces techniques. |
|