Constantes, globales et portée, des mots qui font rêver.
Bonjour,
J'ai lu un peu partout qu'utiliser les macros pour définir ses constantes n'était pas la meilleure solution en C++. Il est de manière générale plutôt recommandé d'utiliser une variable const.
e.g.
Code:
1 2 3 4
| // Pas bien
#define TEXT L"je suis théoriquement une mauvaise constante C++ :'("
// Bien
const wchar_t* text L"je suis théoriquement une bonne constante C++ :D"; |
Oui mais voilà, ça me fait me poser tout un tas de question auxquelles ni mes recherches sur le web ou dans mes livres n'apportent de réponse. Je vous les liste donc point par point. Petite précision, j'utilise le C++11 dans la mesure ou mon compilateur (Visual c++ 2012) me le permet :
1) J'ai lu que seules les constantes ayant un type intégral étaient valides en C++, et que c'est même l'une des limitations que le nouveau mot clé const expr du C++11 permettait de contourner. Seulement mon compilateur ne le supporte pas encore, et j'ai pourtant besoin de déclarer des constantes qui ne sont pas de type intégral comme des double ou des wchar_t. Comment suis-je censé m'y prendre dans ce cas là?
2) Où dois-je déclarer mes constantes? Dans les fichiers source? Les headers? Est-ce que ça change quelque chose?
3) Quelle est la différence concrète entre une constante et une globale? Sont-elles évaluées à la compilation?
4) J'essaye d'utiliser le plus possible les unnamed namespaces en remplacement du mot clé static comme préconisé dans le nouveau standard du C++11. Mais je me demande si c'est vraiment nécessaire lorsque l'on est déjà dans un namespace comme dans l'exemple suivant :
Code:
1 2 3 4 5 6 7 8 9 10
| namespace rwl
{
namespace // Est-ce vraiment utile?
{
int useless_stuffs_in_this_code_count = 999999;
}
// Tout plein de fonctions dégueulasses qui utilisent ma variable.
} |
Car il me semble bien qu'une variable déclarée dans un namespace a déjà sa portée limitée à ce dernier.
5) Un cas concret maintenant. J'ai eu besoin de déclarer une constante accessible partout dans mon espace de nom "rwl". Je m'y suis prit de la manière suivante :
Code:
1 2 3 4 5 6 7 8 9 10 11
| /*
** config.hpp
*/
#pragma once
namespace rwl
{
namespace // Dans le doute...
{
const wchar_t* logfile_rwl = L"Logfiles/rwl.log";
}
} |
Ainsi, je n'ai qu'à inclure ce header pour bénéficier de ma constante là où j'en ai besoin. Est-ce propre? Existe t-il une meilleure solution?
Voilà, en vous remerciant d'avance pour votre aide. :)