Soit un fichier "Foo.cpp" qui utilise la classe truc::Log et un autre fichier "Bar.cpp" qui utilise une autre classe chose::Log.
Admettons que "Foo.cpp" et "Bar.cpp" fassent tous les deux un #include "Log.h", mais chacun visant un fichier différent.
Le jour où un projet contiendra à la fois "Foo.cpp" et "Bar.cpp", on sera dans de beaux draps.
Heureusement, ce problème peut être évité en amont.
Solution 1 : L'inclusion prend en compte le dossier parent.
Une première solution serait que toutes les classes de l'espace de nom truc soient déclarées dans des fichiers d'entête qui sont dans un dossier "Truc". Même logique avec chose.
Alors, "Foo.cpp" pourra faire un #include "Truc/Log.h" et "Bar.cpp" pourra faire un #include "Chose/Log.h".
C'est la stratégie utilisée par Boost : tout est dans l'espace de nom boost et toutes les inclusions sont de la forme #include <boost/qqch> ou #include "boost/qqch".
Solution 2 : Le nom du fichier inclut l'espace de nom.
Une deuxième solution serait que le nom du fichier inclut l'espace de nom. Par exemple, on pourrait choisir le format "EspaceDeNom.NomDeClasse.h".
Ainsi, "Foo.cpp" pourra faire un #include "Truc.Log.h" et "Bar.cpp" pourra faire un #include "Chose.Log.h".
Quelle solution choisir ?
L'inconvénient de la première solution, c'est qu'un développeur pas assez sensibilisé aux collisions de noms pourrait écrire un peu partout des #include "Log.h" sans mentionner explicitement le dossier parent. (Il ajouterait alors ledit dossier à la liste des dossiers d'inclusion du projet pour que ça compile.)
Mais est-ce que la première solution a des avantages que n'a pas la deuxième ?
Partager