L'idiome pImpl, pour Private Implementation, apparaît à quelques endroits dans mes notes de cours (et dans mes prestations), typiquement sous un angle parmi plusieurs (celui, en fait, qui me semble le plus susceptible d'être utile à mes étudiant(e)s). Par acquis de conscience, cependant, voici un petit complément d'information.
On peut aussi dissimuler complètement l'implémentation si on le souhaite, comme on me l'a fait remarquer (j'attribuais la manoeuvre à Sutter, mais on m'a gentiment rappelé que Lakos l'a proposé bien avant). Ça donnerait quelque chose comme ceci (à droite). Dans GenSeq, on peut utiliser un GenSeq::Impl* (un pointeur) dans la mesure où on ne manipule rien qui ait trait à son contenu ou à sa nature (pas d'appel de méthode, incluant le destructeur, tant qu'on n'a pas défini ce que cette classe a comme forme). Jusqu'à preuve du contraire, le type GenSeq::Impl est dit incomplet et ne peut être manipulé en propre, autrement que par des indirections et, même alors, seulement en tant qu'indirection. Cette dernière version, donc, perd l'opportunité du inlining sur GenSeq::prochain(), mais évite, en contrepartie, le polymorphisme lors de l'appel à GenSeq::Impl::prochain(). Notez que, si on souhaite retrouver la possibilité d'avoir plusieurs implémentations distinctes, alors on devra réintroduire la strate polymorphique. Le plus gros avantage de cette version est que le .h n'expose vraiment rien de l'implémentation, donc c'est très agréable pour l'entretien du code. |
Fichier GenSeq.h |
|
|
Fichier GenSeq.cpp | |
|
|
Programme de test | |
|
Voilà!