Langage C++/Portée du code
Une page de Wikiversité.
| Chapitre 10 | |||
| Leçon : Langage C++ | |||
|---|---|---|---|
| Chap. préc. : | Pointeur, Tableaux et références | ||
| Chap. suiv. : | Enumérations | ||
En raison de limitations techniques, la typographie souhaitable du titre, « Langage C++ : Portée du code
Langage C++/Portée du code », n'a pu être restituée correctement ci-dessus.
Sommaire |
[modifier] Portée du code
En C++ la notion de "portée du code" est très importante car elle permet de décrire ce qui se passe, dans quel cadre, et dans une certaine mesure ce qui existe et ce qui n'existe pas encore au travers de contextes d'exécutions.
[modifier] Portée Globale
La portée globale fourni un espace de partage pour toute l'application.
|
Démonstration |
// Début de portée "Globale" // Déclarations Globale d'inclusion d'entête #include <iostream> // nécessaire pour utiliser std::cout //Déclare l'indirection de la portée nommée "std" vers la portée //globale (décompartimentation)(voir portée nommée plus bas) using namespace std; // nécessaire pour utiliser directement cout //Déclaration de constante Globale const int gMaConstanteGlobale = 1; //Déclaration de variable Globale int gMaVariableGlobale = 1; //Déclaration de la méthode globale "main" int main(int argc, char* argv[]) { return 0; } // Fin de portée "Globale" |
La portée Globale englobe tout le programme.
Bien qu'il soit facile de s'en servir de fourre-tout il est déconseillé de le faire. En fait si on le faisait on se retrouverais avec une myriade de types et de noms de variables que l'on ne pourrais pas distinguer des types et variables que l'on crée soit même.
C'est pour cela qu'il existe les autres portées et notamment la portée nommée
[modifier] Portée Nommée "Espace de nom"
La portée nommée (aussi appelé "Espace de nom" du fait du mot clé qui les déclare "namespace") est la portée la plus simple à la disposition du développeur. Elle permet de fournir des noms pour encapsuler des constantes, des variables des types et des méthodes ceci afin de restreindre le champs d'application de ces objets ou de fournir une architecture pour leurs utilisation. Ce type de portée est surtout utilisé dans le but de diviser pour mieux régner et délivre toute sa puissance dans l'implémentation des énumérations au sein d'un IDE graphique.
|
Exemple |
// Début de portée "Globale" // Déclarations Globale d'inclusion d'entête #include <iostream> // nécessaire pour utiliser std::cout //Déclare le déréférencement de la portée nommée "std" vers la portée //globale (décompartimentation)(voir portée nommée plus bas) using namespace std; // nécessaire pour utiliser directement cout //Déclaration de constante Globale const int gMaConstanteGlobale = 1; //Déclaration de variable Globale int gMaVariableGlobale; namespace NVariablesProgramme { //Déclaration d'un nouveau type "NVInteger" basé sur le type int typedef int NInteger; //Déclaration de constante de portée nommée const int nvMaConstanteDePorteeNommee = 2; //Déclaration de variable de portée nommée int nvMaVariableDePorteeNommee; } //Déclaration de la méthode globale "main" int main(int argc, char* argv[]) { // Déréférencement manuel de la porté NVariablesProgramme obligatoire ici // car on à pas utilisé using avec cet espace de nom. NVariablesProgramme::nvMaVariableDePorteeNommee = gMaConstanteGlobale; gMaVariableGlobale = NVariablesProgramme::nvMaConstanteDePorteeNommee; return 0; } // Fin de portée "Globale" |
Il peut être tentant de fournir des noms identiques à des types/variables/méthodes pour des d'espaces de noms différents. Mais cela est à éviter pour trois raisons :
- Cela porte à confusion,
- Ne sachant pas comment les utilisateurs vont les utiliser il vaut mieux éviter les homonymes (risque d'inversion de variables),
- Cela provoque des erreurs de compilations si l'utilisateur met des using sur les deux namespaces simultanément et l'obligera à taper le nom du namespace à chaque fois.
[modifier] Portée Locale
La portée locale et la plus petite portée qui existe. C'est la portée disponible dans les méthodes, les boucles et les structures de tests conditionnels. Elle est généralement déterminée par les accolades. La portée locale est la portée pour laquelle les variables déclarés dans cette même portée sont accessibles. C'est pour cette raison que les portées locales doivent être clairement identifiées et identifiable. Pour cela il est impératif de les écrire toutes explicitement et de bonne pratique de tabuler chaque niveaux de portées afin que l'on puisse facilement les dissocier. La tabulation standard des éditeurs de textes des IDE du marché tourne entre 4 et 6 espaces. Dans le projet LINUX les recommandations de tabulations sont de 8 espaces. La plupart des développeurs modernes vous maudiront si vous tabulez en dessous de 4 espaces.
|
Exemple |
#include <iostream> // nécessaire pour utiliser std::cout using namespace std; // nécessaire pour utiliser directement cout const int gMaConstanteGlobale = 1; int gMaVariableGlobale; namespace NVariablesProgramme { typedef int NInteger; const int nvMaConstanteDePorteeNommee = 2; int nvMaVariableDePorteeNommee; } //Déclaration de la méthode globale "main" int main(int argc, char* argv[]) { // Portée locale de la méthode. int j = 2; // "int j" est créé dans cette portée if(1 < argc) { // Portée locale du test int i = 1; // "int i" existe ici ! j = i; // ici j existe car l'on se trouve dans une portée sous-jacente à celle de sa déclaration. cout << argc << endl; } // ici "int i" n'existe plus car on est sortit de sa portée de définition NVariablesProgramme::nvMaVariableDePorteeNommee = gMaConstanteGlobale; gMaVariableGlobale = NVariablesProgramme::nvMaConstanteDePorteeNommee; return 0; } |
[modifier] Portée "STATIQUE"
La portée statique est la portée des membres statiques du programme. Elle se distingue des autres types de portées par le fait qu'une variable statique existe au chargement du programme dans la mémoire mais n'est accessible que dans la portée locale de sa déclaration.
|
Exemple |
#include <iostream> // nécessaire pour utiliser std::cout using namespace std; // nécessaire pour utiliser directement cout static int vInteger = 0; // Cette variable n'existe qu'en 1 seul exemplaire et est créée // au chargement du programme. Elle est accessible partout car // elle est déclaré dans la portée globale. int TestStatic() { static int vInteger2 = 0; // Cette variable n'existe qu'en 1 seul exemplaire et est créée // au chargement du programme. Elle n'est accessible qu'à l'intérieur // de la méthode car elle n'a pas été déclaré dans la portée globale. // Par contre comme elle est statique et qu'elle à été créé au // chargement du programme elle conserve sa valeur même en dehors de // la méthode. // Cette instruction n'est par conséquent exécutée qu'une seule fois. return vInteger2++; // Comme vous pourrez le constater vInteger2 est incrémenté à chaque // appel ce qui prouve que la déclaration n'est exécutée qu'une seule // fois et que la variable garde sa valeur en dehors de la méthode // contrairement à une variable non statique. } //Déclaration de la méthode globale "main" int main(int argc, char* argv[]) { int vControle = 0; while (vControle < 10) { vControle = TestStatic(); cout << vControle << endl; } return 0; } |