Bonjour,
Soit le code suivant :
Dans mon exemple, les assert servent à vérifier la précondition et la postcondition, et aussi à les documenter, d'où leur présence dans "Math.h". Le détail de l'implémentation se trouve dans la définition de sqrtImpl, dans "Math.cpp".
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 #ifndef INCLUDED__MY_PROJECT__MATH__H #define INCLUDED__MY_PROJECT__MATH__H #include <cassert> namespace MyProject { class Math { public: static double sqrt(double x) { assert(x >= 0); const double result = sqrtImpl(x); assert(result >= 0); return result; } private: static double sqrtImpl(double x); }; } #endif
Dans certains bouts de code utilisateur, pour raccourcir l'écriture MyProject::Math::sqrt, j'aimerais pouvoir aller plus loin que using namespace MyProject; et écrire using MyProject::Math::sqrt;, afin de pouvoir écrire directement sqrt.
De même, dans le cas où je fais appel à beaucoup de fonctions statiques de MyProject::Math, j'aimerais pouvoir écrire quelque chose comme using class MyProject::Math; pour pouvoir utiliser directement ces fonctions sans préfixe.
Mais le code suivant n'est pas valide en C++ :
Actuellement, en C++, le seul moyen de faire cela est de transformer MyProject::Math en espace de nom :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 int main() { { using class MyProject::Math; std::cout << sqrt(9); // Erreur de compilation } { using MyProject::Math::sqrt; // Erreur de compilation std::cout << sqrt(16); // Erreur de compilation } return 0; }
Le problème, c'est que l'on perd la fonctionnalité private. En effet, l'utilisateur peut appeler MyProject::Math::Private::sqrtImpl.
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 #ifndef INCLUDED__MY_PROJECT__MATH__H #define INCLUDED__MY_PROJECT__MATH__H #include <cassert> namespace MyProject::Math { namespace Private { double sqrtImpl(double x); } double sqrt(double x) { assert(x >= 0); const double result = Private::sqrtImpl(x); assert(result >= 0); return result; } } #endif
Au début, j'avais pensé à ajouter au C++ la possibilité d'utiliser private dans un espace de nom :
Mais, contrairement aux classes, les espaces de nom sont extensibles, ce qui permet à l'utilisateur d'écrire :
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 #ifndef INCLUDED__MY_PROJECT__MATH__H #define INCLUDED__MY_PROJECT__MATH__H #include <cassert> namespace MyProject::Math { private: double sqrtImpl(double x); public: double sqrt(double x) { assert(x >= 0); const double result = sqrtImpl(x); assert(result >= 0); return result; } } #endif
et d'appeler directement la fonction triche.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 namespace MyProject::Math { double triche(double x) { return sqrtImpl(x); } }
Du coup, je préfère la possibilité d'avoir l'équivalent de using namespace pour les fonctions statiques des classes.
Seriez-vous d'accord pour l'ajout d'une telle fonctionnalité au langage C++ ?
Partager