Portée en C++

Scope C



Une entité en C++ a un nom, qui peut être déclaré et/ou défini. Une déclaration est une définition, mais une définition n'est pas nécessairement une déclaration. Une définition alloue de la mémoire à l'entité nommée, mais une déclaration peut ou non allouer de la mémoire à l'entité nommée. Une région déclarative est la plus grande partie d'un programme dans laquelle le nom d'une entité (variable) est valide. Cette région est appelée étendue ou étendue potentielle. Cet article explique la portée en C++. De plus, des connaissances de base en C++ sont nécessaires pour comprendre cet article.

Contenu de l'article

Région déclarative et portée

Une région déclarative est la plus grande partie d'un texte de programme dans laquelle le nom d'une entité est valide. C'est la région dans laquelle le nom non qualifié peut être utilisé (vu) pour faire référence à la même entité. Considérez le programme court suivant :







#comprendre
à l'aide de espace de nomsles heures;

annulerfn()
{
entier= 3;
si (1==1)
{
cout<<<<' ';
}
}

entierprincipale()
{
fn();
revenir 0;
}

La fonction fn() a deux blocs : un bloc interne pour la condition if et un bloc externe pour le corps de la fonction. L'identifiant, var, est introduit et vu dans le bloc extérieur. Il est également visible dans le bloc interne, avec l'instruction cout. Les blocs externes et internes sont tous deux la portée du nom, var.



Cependant, le nom, var, peut toujours être utilisé pour déclarer une entité différente telle qu'un flottant dans le bloc interne. Le code suivant illustre cela :



#comprendre
à l'aide de espace de nomsles heures;

annulerfn()
{
entier= 3;
si (1==1)
{
flotter= 7.5;
cout<<<<' ';
}
}

entierprincipale()
{
fn();
revenir 0;
}

La sortie est de 7,5. Dans ce cas, le nom, var, ne peut plus être utilisé dans le bloc interne pour désigner l'entier de valeur 3, qui a été introduit (déclaré) dans le bloc externe. Ces blocs internes sont appelés portée potentielle pour les entités déclarées dans le bloc externe.





Remarque : Une entité du même type, comme celle du bloc externe, peut toujours être déclarée dans le bloc interne. Cependant, dans ce cas, ce qui est valable dans le bloc interne, c'est la nouvelle déclaration et sa signification, tandis que l'ancienne déclaration et sa signification en dehors du bloc interne restent valables dans le bloc externe.

Une déclaration du même nom dans un bloc interne remplace normalement la déclaration du même nom à l'extérieur de ce bloc interne. Les blocs intérieurs peuvent imbriquer d'autres blocs intérieurs.



Portée mondiale

Lorsqu'un programmeur commence juste à taper un fichier, c'est la portée globale. Le programme court suivant illustre cela :

#comprendre
à l'aide de espace de nomsles heures;

flotter= 9.4;

entierprincipale()
{
cout <<<<' ';
cout <<::<<' ';

revenir 0;
}

La sortie est :
9.4
9.4

Dans ce cas, la région ou la portée déclarative de var commence à partir du point de déclaration de var, continue vers le bas jusqu'à la fin du fichier (unité de traduction).

Le bloc de la fonction main() a une portée différente ; il s'agit d'une étendue imbriquée pour l'étendue globale. Pour accéder à une entité de portée globale, à partir d'une portée différente, l'identifiant est utilisé directement ou précédé de l'opérateur de résolution de portée, :: .

Remarque : L'entité main() est également déclarée dans la portée globale.

Portée du bloc

Les instructions if, while, do, for ou switch peuvent chacune définir un bloc. Une telle déclaration est une déclaration composée. Le nom d'une variable déclarée dans un bloc a la portée d'un bloc. Sa portée commence à son point de déclaration et se termine à la fin de son bloc. Le programme court suivant illustre cela pour la variable ident :

#comprendre
à l'aide de espace de nomsles heures;

entierprincipale()
{
si (1==1)
{
/*quelques déclarations*/
entieridentifiant= 5;
cout<<identifiant<<' ';
/*quelques déclarations*/
}
revenir 0;
}

Une variable, telle que ident, déclarée à la portée du bloc est une variable locale.

Une variable déclarée en dehors de la portée du bloc et au-dessus d'elle peut être vue dans l'en-tête du bloc (par exemple, la condition pour le bloc if) et également à l'intérieur du bloc. Le programme court suivant illustre cela pour la variable, identif :

#comprendre
à l'aide de espace de nomsles heures;

entierprincipale()
{
entieridentifiant= 8;

si (identifiant== 8)
{
cout<<identifiant<<' ';
}
revenir 0;
}

La sortie est 8. Il y a deux portées de bloc ici : le bloc pour la fonction main() et l'instruction if-compound imbriquée. Le bloc imbriqué est la portée potentielle du bloc fonction main().

Une déclaration introduite dans une portée de bloc ne peut pas être vue en dehors du bloc. Le programme court suivant, qui ne compile pas, l'illustre avec la variable variab :

#comprendre
à l'aide de espace de nomsles heures;

entierprincipale()
{
si (1 == 1)
{
entiervariable= quinze;
}
cout<<variable<<' '; //erreur : accédé en dehors de sa portée.

revenir 0;
}

Le compilateur produit un message d'erreur pour variab.

Une entité introduite, déclarée dans l'en-tête d'une fonction composée, ne peut pas être vue en dehors (en dessous) de l'instruction composée. Le code de boucle for suivant ne sera pas compilé, ce qui entraînera un message d'erreur :

#comprendre
à l'aide de espace de nomsles heures;

entierprincipale()
{
pour (entierje=0;je<4; ++je)
{
cout<<je<<'';
}
cout<<je<<'';

revenir 0;
}

La variable d'itération, i, est visible à l'intérieur du bloc de boucle for mais pas à l'extérieur du bloc de boucle for.

Portée de la fonction

Un paramètre de fonction est visible dans le bloc fonction. Une entité déclarée dans un bloc fonction est vue depuis le point de déclaration jusqu'à la fin du bloc fonction. Le programme court suivant illustre cela :

#comprendre
#comprendre
à l'aide de espace de nomsles heures;

chaîne fn(chaîne str)
{
carboniserstri[] = 'bananes';
/*autres déclarations*/
chaîne totalStr=p+stri;
revenirTotalStr;
}

entierprincipale()
{
chaîne totStr=fn('manger ');
cout<<totStr<<' ';

revenir 0;
}

La sortie est :
manger des bananes

Remarque : Une entité déclarée en dehors de la fonction (au-dessus) est visible dans la liste des paramètres de la fonction ainsi que dans le bloc fonction.

Étiqueter

La portée d'une étiquette est la fonction dans laquelle elle apparaît. Le code suivant illustre cela :

#comprendre
à l'aide de espace de nomsles heures;

annulerfn()
{
aller àlab;
/*autres déclarations*/
lab: entierne pas= 2;
cout<<ne pas<<' ';
}

entierprincipale()
{
fn();

revenir 0;
}

La sortie est 2.

Portée du dénombrement

Énumération non délimitée
Considérez le bloc if suivant :

si (1==1)
{
énumérer {a, b, c=b+2};
cout<<à<<''<<b<<''<<c<<' ';
}

La sortie est 0 1 3.

La première ligne du bloc est une énumération, a, b et c sont ses énumérateurs. La portée d'un énumérateur commence du point de déclaration à la fin du bloc englobant de l'énumération.

L'instruction suivante ne sera pas compilée car le point de déclaration de c est après celui de a :

énumérer {à=c+2, avant JC};

Le segment de code suivant ne sera pas compilé car les énumérateurs sont accessibles après le bloc englobant de l'énumération :

si (1==1)
{
énumérer {a, b, c=b+2};
}
cout<<à<<''<<b<<''<<c<<' '; //erreur : hors de portée

L'énumération ci-dessus est décrite comme une énumération non délimitée et ses énumérateurs sont décrits comme des énumérateurs non délimités. C'est parce qu'il ne commence que par le mot réservé, enum. Les énumérations qui commencent par enum class ou enum struct sont décrites comme des énumérations étendues. Leurs énumérateurs sont décrits comme des énumérateurs délimités.

Énumération de portée
La déclaration suivante est OK :

énumérer classerMasculin{a, b, c=b+2};

Il s'agit d'un exemple d'énumération étendue. Le nom de la classe est nam. Ici, la portée de l'énumérateur commence du point de déclaration à la fin de la définition de l'énumération, et non à la fin du bloc englobant de l'énumération. Le code suivant ne compilera pas :

si (1==1)
{
énumérer classerMasculin{a, b, c=b+2};
cout<<à<<''<<b<<''<<c<<' '; //erreur : hors de portée pour la classe enum ou la structure enum
}

Portée de la classe

Avec une portée normale, la région déclarative commence à partir d'un point, puis continue et s'arrête à un point différent. La portée existe dans une région continue. Avec la classe, la portée d'une entité peut être dans différentes régions qui ne sont pas réunies. Les règles pour les blocs imbriqués s'appliquent toujours. Le programme suivant illustre cela :

#comprendre
à l'aide de espace de nomsles heures;

//Classe de base
classerCla
{
privé:
entiermemP= 5;
protégé:
entiermemPro= 9;
Publique:
annulerfn()
{
cout<<memP<<' ';
}
};

//Classe dérivée
classerDerCla: PubliqueCla
{
Publique:
entierderMem=memPro;
};
entierprincipale()
{
Cla obj;
obj.fn();
DerCla derObj;
cout<<derObj.derMem<<' ';

revenir 0;
}

La sortie est :
5
9

Dans la classe Cla, la variable memP est vue au point de déclaration. Après cela, la partie courte de protected est ignorée, puis réexaminée dans le bloc fonction membre de classe. La classe dérivée est ignorée, puis réexaminée au niveau de la portée de la fonction main() (bloc).

Dans la classe Cla, la variable memPro est vue au moment de la déclaration. La partie de la fonction publique fn() est ignorée, puis vue dans le bloc de description de classe dérivée. Il est revu en bas dans la fonction main().

Opérateur de résolution de portée
L'opérateur de résolution de portée en C++ est :: . Il est utilisé pour accéder à un membre statique de la classe. Le programme suivant illustre cela :

#comprendre
à l'aide de espace de nomsles heures;

classerCla
{
Publique:
statique entier constmeme= 5;
Publique:
statique annulerfn()
{
cout<<meme<<' ';
}
};
entierprincipale()
{
cout<<Cla::meme<<' ';
Cla::fn();

revenir 0;
}

La sortie est :
5
5

Les membres statiques sont visibles dans le bloc fonction main(), accessible à l'aide de l'opérateur de résolution de portée.

Portée des paramètres du modèle

La portée normale d'un nom de paramètre de modèle commence du point de déclaration à la fin de son bloc, comme dans le code suivant :

modèle<nom de typeT,nom de typeU> structureÂge
{
Jean Jean= Onze;
Toi Pierre= 12.3;
T Marie= 13;
U joie= 14.6;
};

U et T sont visibles à l'intérieur du bloc.

Pour un prototype de fonction modèle, la portée commence du point de déclaration à la fin de la liste des paramètres de la fonction, comme dans l'instruction suivante :

modèle<nom de typeT,nom de typeU> annulerfonction(Vous non, u cha,const carboniser *p);

Cependant, en ce qui concerne la description de la classe (définition), la portée peut également être de différentes parties comme dans le code suivant :

#comprendre
à l'aide de espace de nomsles heures;

modèle<classerT,classerU> classerLa Cla
{
Publique:
t num;
statiqueU ch;

annulerfonction(Toi père,const carboniser *p)
{
cout << 'Il y a ' <<sur une<< 'les livres valent' <<non<<p<< ' dans le magasin.' << ' ';
}
statique annuleramusant(U ch)
{
si (ch== 'à')
cout << 'Fonction membre statique officielle' << ' ';
}
};

entierprincipale()
{
La Cla<entier,carboniser>obj;
obj.sur une = 12;
obj.fonction('$','500');

revenir 0;
}

Nom caché

Un exemple de masquage de nom se produit lorsque le nom du même type d'objet est à nouveau déclaré dans un bloc imbriqué. Le programme suivant illustre cela :

#comprendre
à l'aide de espace de nomsles heures;

annulerfn()
{
entier= 3;
si (1==1)
{
entier= 4;
cout<<<<' ';
}
cout<<<<' ';
}

entierprincipale()
{
fn();
revenir 0;
}

La sortie est :
4
3

C'est parce que var dans le bloc imbriqué cachait var dans le bloc extérieur.

Possibilité de répéter la déclaration dans le même périmètre

Le point de la déclaration est l'endroit où le nom est introduit (pour la première fois) dans sa portée.

Prototype de fonction
Des entités différentes, même de types différents, ne peuvent normalement pas être déclarées dans la même portée. Cependant, un prototype de fonction peut être déclaré plusieurs fois dans la même portée. Le programme suivant avec deux prototypes de fonction et la définition de fonction correspondante illustre cela :

#comprendre
à l'aide de espace de nomsles heures;

annulerfn(entiersur une);
annulerfn(entiersur une);

annulerfn(entiersur une)
{
cout<<sur une<<' ';
}

entierprincipale()
{
fn(5);

revenir 0;
}

Le programme fonctionne.

Fonctions surchargées
Les fonctions surchargées sont des fonctions portant le même nom mais des signatures de fonction différentes. Autre exception, les fonctions surchargées portant le même nom peuvent être définies dans la même portée. Le programme suivant illustre cela :

#comprendre
à l'aide de espace de nomsles heures;

annulerfn(entiersur une)
{
cout<<sur une<<' ';
}

annulerfn(flotternon)
{
cout<<non<<' ';
}

entierprincipale()
{
fn(5);
flotterflt= 8.7;
fn(flt);

revenir 0;
}

La sortie est :
5
8.7

Les fonctions surchargées ont été définies dans le périmètre global.

Portée de l'espace de noms

Namespace Scope mérite son propre article. Ledit article a été écrit pour ce site Web, linuxhint.com. Tapez simplement les mots de recherche Namespace Scope dans la zone de recherche de ce site (page) et cliquez sur OK, et vous obtiendrez l'article.

Portée en différentes portions

La classe n'est pas le seul schéma où la portée peut être dans différentes parties. Le spécificateur ami, certaines utilisations du spécificateur de type élaboré et les directives d'utilisation sont d'autres schémas où la portée est à des endroits différents - pour plus de détails, voir plus loin.

Conclusion

Une étendue est une région déclarative. Une région déclarative est la plus grande partie d'un texte de programme dans laquelle le nom d'une entité est valide. Il peut être divisé en plusieurs parties conformément à certains schémas de programmation, tels que les blocs imbriqués. Les portions qui n'ont pas le point de déclaration forment la portée potentielle. La portée potentielle peut ou non avoir la déclaration.