Ambito in C ++

Ambito in C ++

Un'entità in C ++ ha un nome, che può essere dichiarato e/o definito. Una dichiarazione è una definizione, ma una definizione non è necessariamente una dichiarazione. Una definizione alloca la memoria per l'entità nominata, ma una dichiarazione può o meno allocare la memoria per l'entità nominata. Una regione dichiarativa è la parte più grande di un programma in cui è valido il nome di un'entità (variabile). Quella regione è chiamata portata o potenziale portata. Questo articolo spiega lo scoping in c++. Inoltre, è necessaria la conoscenza di base di C ++ per comprendere questo articolo.

Contenuto dell'articolo

  • Regione dichiarativa e portata
  • Portata globale
  • Variabili globali e portata globale
  • Scope di blocchi
  • Ambito da funzione
  • Ambito di classe
  • Ambito di enumerazione
  • Variabile globale
  • Ambito parametro modello
  • Nome che si nasconde
  • Possibilità di ripetere la dichiarazione nello stesso ambito
  • Ambito dello spazio dei nomi
  • Portata in porzioni diverse
  • Conclusione

Regione dichiarativa e portata

Una regione dichiarativa è la parte più grande di un testo del programma in cui è valido il nome di un'entità. La regione in cui è possibile utilizzare il nome non qualificato (visto) per fare riferimento alla stessa entità. Considera il seguente breve programma:

#includere
Utilizzo dello spazio dei nomi std;
void fn ()

int var = 3;
if (1 == 1)

cout<

int main ()

fn ();
restituzione 0;

La funzione fn () ha due blocchi: un blocco interno per la condizione if e un blocco esterno per il corpo della funzione. L'identificatore, var, viene introdotto e visto nel blocco esterno. È anche visto nel blocco interno, con l'istruzione Cout. I blocchi esterni e interni sono l'ambito del nome, var.

Tuttavia, il nome, var, può ancora essere usato per dichiarare un'entità diversa, come un galleggiante, nel blocco interno. Il seguente codice illustra questo:

#includere
Utilizzo dello spazio dei nomi std;
void fn ()

int var = 3;
if (1 == 1)

float var = 7.5;
cout<

int main ()

fn ();
restituzione 0;

L'output è

7.5

In questo caso, il nome, var, non può più essere utilizzato nel blocco interno per fare riferimento all'intero valore 3, che è stato introdotto (dichiarato) nel blocco esterno. Tali blocchi interni sono indicati come potenziale portata per le entità dichiarate nel blocco esterno.

Nota: un'entità dello stesso tipo, come il blocco esterno, può ancora essere dichiarata nel blocco interno. Tuttavia, in questo caso, la nuova dichiarazione e il suo significato sono validi nel blocco interno, mentre la vecchia dichiarazione e significato al di fuori del blocco interno rimangono validi solo nel blocco esterno.

Una dichiarazione con lo stesso nome in un blocco interno normalmente sovrascrive la dichiarazione con lo stesso nome al di fuori di quel blocco interno. I blocchi interni possono nidificare altri blocchi interni.

Portata globale

Quando un programmatore inizia a digitare un file, questo è l'ambito globale. Il seguente breve programma illustra questo:

#includere
Utilizzo dello spazio dei nomi std;
float var = 9.4;
int main ()

cout <cout <<::var<<'\n';
restituzione 0;

L'output è:

9.4
9.4

In questo caso, la regione dichiarativa o l'ambito di VAR inizia dal punto di dichiarazione per var e continua verso il basso fino alla fine del file (unità di traduzione).

Il blocco della funzione principale () è un ambito diverso; è un ambito nidificato per l'ambito globale. Per accedere a un'entità dell'ambito globale da un ambito diverso, l'identificatore viene utilizzato direttamente o preceduto dall'operatore di risoluzione dell'ambito, :::: .

Nota: l'entità, main (), è anche dichiarata nell'ambito globale.

Scope di blocchi

Le istruzioni IF, why, do, o o switch possono definire ciascuno un blocco. Tale affermazione è un'affermazione composta. Il nome di una variabile dichiarata in un blocco ha l'ambito di un blocco. Il suo ambito inizia al suo punto di dichiarazione e termina alla fine del suo blocco. Il seguente breve programma lo illustra per la variabile, IDENT:

#includere
Utilizzo dello spazio dei nomi std;
int main ()

if (1 == 1)

/*Alcune affermazioni*/
int ident = 5;
cout</*Alcune affermazioni*/

restituzione 0;

Una variabile, come l'identità, dichiarata a blocchi è una variabile locale.

Una variabile dichiarata al di fuori dell'ambito del blocco e sopra può essere vista nell'intestazione del blocco (E.G., condizione per if-block) e all'interno del blocco. Il seguente breve programma lo illustra per la variabile, Identif:

#includere
Utilizzo dello spazio dei nomi std;
int main ()

int identif = 8;
if (Identif == 8)

cout<
restituzione 0;

L'output è,

8

Esistono due ambiti a blocchi: il blocco per la funzione principale () e l'istruzione IF-compone nidificata. Il blocco nidificato è l'ambito potenziale del blocco funzione principale ().

Una dichiarazione introdotta in un ambito di blocco non può essere vista al di fuori del blocco. Il seguente breve programma, che non si compila, lo illustra con la variabile, variab:

#includere
Utilizzo dello spazio dei nomi std;
int main ()

if (1 == 1)

int variab = 15;

cout<restituzione 0;

Il compilatore produce un messaggio di errore per variab.

Un'entità introdotta, dichiarata nell'intestazione di una funzione composta, non può essere vista al di fuori (sotto) l'istruzione composta. Il seguente codice per loop non si compilerà, risultando in un messaggio di errore:

#includere
Utilizzo dello spazio dei nomi std;
int main ()

per (int i = 0; i<4; ++i)

cout<
cout<restituzione 0;

La variabile di iterazione, io, è vista all'interno del blocco per loop ma non al di fuori del blocco per loop.

Ambito da funzione

Un parametro di funzione è visualizzato nel blocco funzione. Un'entità dichiarata in un blocco di funzione è vista dal punto di dichiarazione alla fine del blocco funzione. Il seguente breve programma illustra questo:

#includere
#includere
Utilizzo dello spazio dei nomi std;
String fn (stringa str)

Char Stri [] = "Bananas";
/*altre dichiarazioni*/
String totalstr = str + stri;
restituire totaltalstr;

int main ()

string totstr = fn ("mangiare");
cout<restituzione 0;

L'output è:

Mangiare banane

Nota: un'entità dichiarata al di fuori della funzione (sopra di essa) può essere visualizzata nell'elenco dei parametri della funzione e nel blocco funzione.

Etichetta

L'ambito di un'etichetta è la funzione in cui appare. Il seguente codice illustra questo:

#includere
Utilizzo dello spazio dei nomi std;
void fn ()

goto labl;
/*altre dichiarazioni*/
LABL: int Inter = 2;
cout<
int main ()

fn ();
restituzione 0;

L'output è

2

Ambito di classe

Con lo scoping normale, la regione dichiarativa inizia da un punto del programma, continua e si ferma in un punto diverso. L'ambito esiste in una regione continua. Con la classe, l'ambito di un'entità può trovarsi in diverse regioni che non sono unite insieme. Le regole per i blocchi nidificati si applicano ancora. Il seguente programma illustra questo:

#includere
Utilizzo dello spazio dei nomi std;
// classe base
Cla di classe

privato:
int memp = 5;
protetto:
int Mempro = 9;
pubblico:
void fn ()

cout<
;
// classe derivata
Classe Dercla: CLA pubblico

pubblico:
int dermem = memor;
;
int main ()

Cla OBJ;
obj.fn ();
Dercla derobj;
cout<restituzione 0;

L'output è:

5
9

Nella classe CLA, il PEMP variabile, è visto nel punto di dichiarazione. Successivamente, la parte breve di "protetta" viene saltata e vista nel blocco delle funzioni del membro della classe. La classe derivata viene saltata e vista nell'ambito di funzione principale () (blocco).

Nella classe CLA, la variabile, Mempro, è vista nel punto di dichiarazione. La parte della funzione pubblica fn () viene saltata e quindi vista nel blocco di descrizione della classe derivata. Viene visto di nuovo nella funzione principale ().

Operatore di risoluzione dell'ambito

L'operatore di risoluzione dell'ambito in C ++ è :: . Viene utilizzato per accedere a un membro statico della classe. Il seguente programma illustra questo:

#includere
Utilizzo dello spazio dei nomi std;
Cla di classe

pubblico:
static int const mem = 5;
pubblico:
statico void fn ()

cout<
;
int main ()

cout<Cla :: fn ();
restituzione 0;

L'output è:

5
5

I membri statici sono visti nel blocco funzione principale (), accessibile utilizzando l'operatore di risoluzione dell'ambito.

Ambito di enumerazione

Enumerazione non copicata

Considera quanto segue se blocco:

if (1 == 1)

enum a, b, c = b+2;
cout<

L'output è:

0 1 3

La prima riga nel blocco è un enumerazione; A, B e C sono i suoi enumeratori. L'ambito di un enumeratore inizia dal punto della sua dichiarazione, fino alla fine del blocco racchiuso dell'enumerazione.

La seguente dichiarazione non si compilerà perché il punto di dichiarazione di C è dopo quello di A:

enum a = c+2, b, c;

Il seguente segmento di codice non si compilerà perché gli enumeratori sono accessibili dopo il blocco di enumerazione:

if (1 == 1)

enum a, b, c = b+2;

cout<

L'enumerazione precedente è descritta come un enumerazione non scopita e i suoi enumeratori sono definiti come enumeratori non scopiti. Questo perché inizia solo con la parola riservata, enum. Le elencazioni che iniziano con la classe Enum o Enum sono descritte come enumerazioni con ambito. I loro enumeratori sono definiti come enumeratori con ambito.

Enumerazione ammessa

La seguente dichiarazione è OK:

enum class nam a, b, c = b+2;

Questo è un esempio di enumerazione ampliata. Il nome della classe è nam. Qui, l'ambito dell'enumeratore inizia dal punto di dichiarazione alla fine della definizione di enumerazione e non alla fine del blocco racchiuso per l'enumerazione. Il seguente codice non si compilerà:

if (1 == 1)

enum class nam a, b, c = b+2;
cout<

Semplice utilizzo dell'enumerazione ampliata

Il seguente codice mostra un modo semplice di utilizzare l'enumerazione ammessa:

if (1 == 1)

enum nam a, b, c = b+2;
cout << c << endl; //simple usage

L'output è 3, poiché B è 1 ('a' è 0).

Variabile globale

Una variabile globale è una variabile dichiarata nell'ambito globale. Quando un programmatore inizia a digitare un file, questo è l'ambito globale. Considera il seguente programma:

#includere
Utilizzo dello spazio dei nomi std;
char va = 'a';
int main ()

cout <cout <<::va<<'\n';
restituzione 0;

L'output è:

UN
UN

In questo programma, la porzione o l'ambito di VA inizia dal punto di dichiarazione di VA e continua verso il basso fino alla fine dell'unità di traduzione (file).

Il corpo della funzione principale () è un ambito diverso a sé stante; L'ambito globale nidifica l'ambito di funzione principale ().

La variabile VA è una variabile di portata globale o semplicemente variabile globale perché può essere vista ovunque nel file, a partire da dove è stata dichiarata. Può essere visto nell'ambito di funzione principale ().

Per accedere a una variabile globale (variabile dell'ambito globale) da un ambito diverso, il nome della variabile viene utilizzato direttamente o preceduto dall'operatore di risoluzione dell'ambito, :: come mostrato nel programma sopra.

L'istruzione IF, why, do, per o switch può definire un blocco. Tale affermazione è un'affermazione composta. Il nome di una variabile dichiarata in un blocco ha l'ambito di un blocco. Il suo ambito inizia al suo punto di dichiarazione e termina alla fine del suo blocco. Il seguente breve programma lo illustra per la variabile, IDENT:

#includere
Utilizzo dello spazio dei nomi std;
int main ()

if (1 == 1)

/*Alcune affermazioni*/
int ident = 5;
cout</*Alcune affermazioni*/

restituzione 0;

Una variabile, come l'identità, dichiarata a blocchi è una variabile locale.

Una variabile dichiarata al di fuori dell'ambito del blocco e sopra può essere vista nell'intestazione del blocco (E.G., condizione per if-block) e all'interno del blocco. Il seguente breve programma lo illustra per la variabile, Identif:

#includere
Utilizzo dello spazio dei nomi std;
int main ()

int identif = 8;
if (Identif == 8)

cout<
restituzione 0;

L'output è,

8

Ci sono due ambiti di blocchi qui: il blocco per la funzione principale () e l'istruzione IF-COMPOUND nidificata. Il blocco nidificato è l'ambito potenziale del blocco funzione principale ().

Una dichiarazione introdotta in un ambito di blocco non può essere vista al di fuori del blocco. Il seguente breve programma, che non si compila, lo illustra con la variabile, variab:

#includere
Utilizzo dello spazio dei nomi std;
int main ()

if (1 == 1)

int variab = 15;

cout<restituzione 0;

Il compilatore produce un messaggio di errore per variab.

Un'entità introdotta, dichiarata nell'intestazione di una funzione composta, non può essere vista al di fuori (sotto) l'istruzione composta. Il seguente codice per loop non si compilerà, risultando in un messaggio di errore:

#includere
Utilizzo dello spazio dei nomi std;
int main ()

per (int i = 0; i<4; ++i)

cout<
cout<restituzione 0;

La variabile di iterazione, io, è vista all'interno del blocco per loop ma non al di fuori del blocco per loop.

Una variabile dichiarata nell'ambito globale è una variabile globale. Può essere visto all'interno di un ambito di blocco. Il seguente programma illustra questo:

#includere
Utilizzo dello spazio dei nomi std;
int glb = 5;
int main ()

cout << glb << endl;
restituzione 0;

L'output è 5.

Riassegnazione non consentita nell'ambito globale

Nel programma precedente, la dichiarazione:

int glb = 5;

È una dichiarazione con l'inizializzazione (prima assegnazione del valore) contemporaneamente. Nel seguente programma, l'affermazione "int glb;" non ha assegnato lo zero per impostazione predefinita. La linea dopo (GLB = 5;) prova la riassegnazione del valore, 5, nell'ambito globale. Questo crea un errore e il programma non compila. Il programma è:

#includere
Utilizzo dello spazio dei nomi std;
int glb;
GLB = 5;
int main ()

cout << glb << endl;
restituzione 0;

Tuttavia, la riassegnazione avrà luogo in un ambito locale (blocco), come mostrato nel seguente programma:

#includere
Utilizzo dello spazio dei nomi std;
int glb;
int main ()

if (1 == 1)
GLB = 5;
cout << glb << endl;

restituzione 0;

L'output è 5.

Puntatore globale

Quando un puntatore viene dichiarato nell'ambito globale, può essere visto in un ambito nidificato. Un puntatore dichiarato in un ambito nidificato non può essere visto al di fuori dell'ambito nidificato. Esistono due modi per dichiarare un puntatore. Un puntatore può essere dichiarato con un incarico pratico (di un indirizzo). Un puntatore può essere dichiarato senza un incarico pratico. Se il puntatore viene dichiarato senza un incarico pratico nell'ambito globale, allora non può essere riassegnato nell'ambito globale. Tuttavia, in questo caso, può essere riassegnato in un ambito nidificato.

Array globale

Quando un array viene dichiarato nell'ambito globale, può essere visto in un ambito nidificato. Un array dichiarato in un ambito nidificato, non può essere visto al di fuori dell'ambito nidificato. Ci sono due modi per dichiarare un array. Un array può essere dichiarato con un incarico pratico (di un indirizzo). Un array può essere dichiarato senza incarico pratico. Se l'array viene dichiarato senza un incarico pratico nell'ambito globale, allora non può essere riassegnato nell'ambito globale. Tuttavia, può essere riassegnato in un ambito nidificato (elemento per elemento).

Ambito parametro modello

L'ambito normale di un nome del parametro modello inizia dal punto di dichiarazione alla fine del suo blocco, come nell'esempio seguente:

modello Struttion Età

T John = 11;
U peter = 12.3;
T Maria = 13;
U gioia = 14.6;
;

U e t sono visti all'interno del blocco.

Per un prototipo di funzione modello, l'ambito inizia dal punto di dichiarazione alla fine dell'elenco dei parametri della funzione, come nella seguente istruzione:

modello void func (t no, u cha, const char *str);

Tuttavia, quando si tratta della descrizione della classe (definizione), l'ambito può anche essere di parti diverse, come nel seguente programma di esempio:

#includere
Utilizzo dello spazio dei nomi std;
modello Classe thecla

pubblico:
T num;
statico u ch;
void func (u cha, const char *str)

cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

statico vuoto divertente (u ch)

if (ch == 'a')
cout << "Official static member function" << '\n';

;
int main ()

Thecla obj;
obj.num = 12;
obj.func ('$', "500");
restituzione 0;

Nome che si nasconde

Un esempio di nascondiglio si verifica quando il nome dello stesso tipo di oggetto viene declassato in un blocco nidificato. Il seguente programma illustra questo:

#includere
Utilizzo dello spazio dei nomi std;
void fn ()

int var = 3;
if (1 == 1)

int var = 4;
cout<
cout<
int main ()

fn ();
restituzione 0;

L'output è:

4
3

È perché var nel blocco nidificato nascosto var nel blocco esterno.

Possibilità di ripetere la dichiarazione nello stesso ambito

Il punto della dichiarazione è in cui il nome viene introdotto (per la prima volta) nel suo ambito.

Prototipo di funzione

Entità diverse, anche di tipi diversi, non possono normalmente essere dichiarati nello stesso ambito. Tuttavia, un prototipo di funzione può essere dichiarato più di una volta nello stesso ambito. Il seguente programma con due prototipi di funzioni e la definizione della funzione corrispondente illustra questo:

#includere
Utilizzo dello spazio dei nomi std;
void fn (int num);
void fn (int num);
void fn (int num)

cout<
int main ()

fn (5);
restituzione 0;

Il programma funziona.

Funzioni sovraccariche

Le funzioni sovraccarichi sono funzioni con lo stesso nome ma con diverse firme della funzione. Come un'altra eccezione, le funzioni sovraccarichi con lo stesso nome possono essere definite nello stesso ambito. Il seguente programma illustra questo:

#includere
Utilizzo dello spazio dei nomi std;
void fn (int num)

cout<
void fn (float no)

cout<
int main ()

fn (5);
float flt = 8.7;
fn (flt);
restituzione 0;

L'output è:

5
8.7

Le funzioni sovraccariche sono state definite nell'ambito globale.

Ambito dello spazio dei nomi

Poiché due variabili diverse possono avere lo stesso nome e per differenziarle, le variabili devono essere dichiarate in due diversi spazi dei nomi. Uno spazio dei nomi è un blocco con un nome, con le sue entità nominate. Il nome di uno spazio dei nomi è il nome del blocco. Due spazi nomi diversi possono avere entità con gli stessi nomi. Il seguente programma illustra questo:

#includere
Utilizzo dello spazio dei nomi std;
spazio dei nomi Na

Char Ch1;
char ch2 = 'q';

spazio dei nomi nb

Char Ch1;
char ch2 = 'y';

int main ()

Na :: ch1 = 'p';
cout << NA::ch1 << endl;
Nb :: ch1 = 'x';
cout << NB::ch1 << endl;
restituzione 0;

L'output è:

P
X

Ci sono due spazi dei nomi: NA e NB. Lo spazio predefinito per NA è il suo blocco. Lo spazio predefinito per NB è anche il suo blocco. Si noti che le entità nei due blocchi diversi hanno gli stessi nomi. Per dichiarare uno spazio dei nomi, inizia con la parola riservata, spazio dei nomi; Segue uno spazio, quindi il blocco con le sue entità.

Per accedere a un'entità al di fuori del blocco dello spazio dei nomi, inizia con il nome dello spazio dei nomi. Questo è seguito dall'operatore di risoluzione dell'ambito e quindi dal nome dell'entità.

L'ambito della variabile, Na :: Ch1, inizia dal punto di dichiarazione di CH1 nel blocco NA. Termina alla fine del blocco NA e poi appare in qualsiasi linea all'esterno (e sotto) il blocco, dove viene utilizzato "Na ::". L'ambito della variabile, NB :: CH1, inizia dal punto di dichiarazione di CH1 nel blocco NB. Termina alla fine del blocco NB e appare in qualsiasi linea all'esterno (e sotto) il blocco, dove viene utilizzato "nb ::".

Un ambito dello spazio dei nomi si riferisce a un'entità dichiarata nel blocco dello spazio dei nomi. L'ambito dell'entità dello spazio dei nomi è il blocco dello spazio dei nomi e qualsiasi riga al di fuori del blocco che utilizza il nome dello spazio dei nomi.

Portata in porzioni diverse

Gli ampli dello spazio di classe e nomi precedenti hanno illustrato come un ambito può trovarsi in diverse parti del testo del programma. Un altro buon esempio è l'amico specificatore.

Specificatore amico

Se la classe C è dichiarata amica alla Classe A, nella definizione di Classe A, allora tutte le funzioni dei membri pubblici della Classe C possono accedere ai membri dei dati privati ​​(e alle funzioni dei membri privati) della classe A. Il seguente programma illustra questo:

#includere
Utilizzo dello spazio dei nomi std;
classe A
privato: int d = 5;
Classe di amici C;
;
Classe B
/*
public: int fb ()
Aa;
restituire a.D;

*/
;
Classe C
public: int fc ()
Aa;
restituire a.D;

;
int main ()

Aa;
B B;
C c;
// int ret1 = b.fb ();
int ret2 = c.fc ();
cout << ret2 << endl;
restituzione 0;

L'output è 5. Nella definizione di classe A, la classe C è dichiarata amica alla classe A. Quindi, fc () della definizione di classe C, può vedere la definizione di classe A. Il programma compila. Se i simboli dei commenti vengono rimossi, il programma non si compilerà perché la classe B non è stata dichiarata un amico alla classe A.

L'ambito della variabile privata B inizia dal suo punto di dichiarazione e termina alla fine del blocco di classe A. Appare anche nella funzione FC () nella classe C, che è un amico della classe A. Le due porzioni per l'ambito sono il blocco di classe A e il blocco funzione fc ().

Conclusione

Un campo di applicazione è una regione dichiarativa. Una regione dichiarativa è la parte più grande di un testo del programma in cui è valido il nome di un'entità. Può essere diviso in più di una porzione con alcuni schemi di programmazione, come i blocchi nidificati. Le porzioni che non hanno il punto di dichiarazione formano il potenziale ambito. Il potenziale ambito può o meno avere la dichiarazione.