Domeniul de aplicare în C ++

Scope C



O entitate din C ++ are un nume, care poate fi declarat și / sau definit. O declarație este o definiție, dar o definiție nu este neapărat o declarație. O definiție alocă memorie pentru entitatea numită, dar o declarație poate sau nu să aloce memorie pentru entitatea numită. O regiune declarativă este cea mai mare parte a unui program în care numele unei entități (variabilă) este valid. Regiunea respectivă se numește domeniu sau potențial. Acest articol explică domeniul de aplicare în C ++. Mai mult, cunoștințele de bază în C ++ sunt necesare pentru a înțelege acest articol.

Conținutul articolului

Regiunea declarativă și domeniul de aplicare

O regiune declarativă este cea mai mare parte a textului programului în care numele unei entități este valid. Este regiunea în care numele necalificat poate fi folosit (văzut) pentru a se referi la aceeași entitate. Luați în considerare următorul program scurt:







#include
folosind spațiu de numeore;

nulfn()
{
intUnde= 3;
dacă (1==1)
{
cost<<Unde<<' n';
}
}

intprincipal()
{
fn();
întoarcere 0;
}

Funcția fn () are două blocuri: un bloc interior pentru condiția if și un bloc exterior pentru corpul funcției. Identificatorul, var, este introdus și văzut în blocul exterior. Se vede și în blocul interior, cu declarația cout. Blocurile exterioare și interioare sunt ambele scopuri pentru numele, var.



Cu toate acestea, numele, var, poate fi încă folosit pentru a declara o entitate diferită, cum ar fi un float în blocul interior. Următorul cod ilustrează acest lucru:



#include
folosind spațiu de numeore;

nulfn()
{
intUnde= 3;
dacă (1==1)
{
plutiUnde= 7.5;
cost<<Unde<<' n';
}
}

intprincipal()
{
fn();
întoarcere 0;
}

Ieșirea este de 7,5. În acest caz, numele, var, nu mai poate fi utilizat în blocul interior pentru a se referi la întregul valorii 3, care a fost introdus (declarat) în blocul exterior. Astfel de blocuri interioare sunt denumite potențiale scopuri pentru entitățile declarate în blocul exterior.





Notă: O entitate de același tip, precum cea a blocului exterior, poate fi declarată în continuare în blocul interior. Cu toate acestea, în acest caz, ceea ce este valabil în blocul interior este noua declarație și semnificația acesteia, în timp ce vechea declarație și semnificația sa în afara blocului interior rămân valabile în blocul exterior.

O declarație cu același nume într-un bloc interior suprascrie în mod normal declarația cu același nume în afara acelui bloc interior. Blocurile interioare pot cuibări alte blocuri interioare.



Domeniul de aplicare global

Când un programator începe doar să tasteze un fișier, acesta este domeniul global de aplicare. Următorul program scurt ilustrează acest lucru:

#include
folosind spațiu de numeore;

plutiUnde= 9.4;

intprincipal()
{
cost <<Unde<<' n';
cost <<::Unde<<' n';

întoarcere 0;
}

Ieșirea este:
9.4
9.4

În acest caz, regiunea declarativă sau domeniul pentru var începe de la punctul de declarație pentru var, continuă în jos până la sfârșitul fișierului (unitate de traducere).

Blocul funcției main () este un domeniu diferit; este un domeniu imbricat pentru domeniul global. Pentru a accesa o entitate din domeniul global, dintr-un alt domeniu, identificatorul este utilizat direct sau precedat de operatorul de rezoluție a domeniului, ::.

Notă: Entitatea, main (), este, de asemenea, declarată în domeniul global.

Scopul blocului

Instrucțiunea if, while, do, for sau switch poate defini fiecare un bloc. O astfel de afirmație este o afirmație compusă. Numele unei variabile declarate într-un bloc are domeniul de aplicare al unui bloc. Domeniul său de aplicare începe la punctul de declarație și se termină la sfârșitul blocului său. Următorul program scurt ilustrează acest lucru pentru variabila, ident:

#include
folosind spațiu de numeore;

intprincipal()
{
dacă (1==1)
{
/ * câteva afirmații * /
intident= 5;
cost<<ident<<' n';
/ * câteva afirmații * /
}
întoarcere 0;
}

O variabilă, cum ar fi ident, declarată la sfera blocului este o variabilă locală.

O variabilă declarată în afara scopului blocului și deasupra acestuia poate fi văzută în antetul blocului (de exemplu, condiția blocului if) și, de asemenea, în cadrul blocului. Următorul program scurt ilustrează acest lucru pentru variabila, identif:

#include
folosind spațiu de numeore;

intprincipal()
{
intidentif= 8;

dacă (identif== 8)
{
cost<<identif<<' n';
}
întoarcere 0;
}

Ieșirea este 8. Există două domenii de bloc aici: blocul pentru funcția main () și instrucțiunea imbricată dacă-compus. Blocul imbricat este domeniul potențial al blocului funcțional main ().

O declarație introdusă într-un domeniu de bloc nu poate fi văzută în afara blocului. Următorul program scurt, care nu compilează, ilustrează acest lucru cu variabila, variab:

#include
folosind spațiu de numeore;

intprincipal()
{
dacă (1 == 1)
{
intvariab= cincisprezece;
}
cost<<variab<<' n'; // eroare: accesată în afara scopului său.

întoarcere 0;
}

Compilatorul produce un mesaj de eroare pentru variab.

O entitate introdusă, declarată în antetul unei funcții compuse, nu poate fi văzută în afara (dedesubt) instrucțiunii compuse. Următorul cod pentru buclă nu se va compila, rezultând un mesaj de eroare:

#include
folosind spațiu de numeore;

intprincipal()
{
pentru (inteu=0;eu<4; ++eu)
{
cost<<eu<<'';
}
cost<<eu<<'';

întoarcere 0;
}

Variabila de iterație, i, este văzută în interiorul blocului pentru buclă, dar nu în afara blocului pentru buclă.

Domeniul funcției

Un parametru funcțional este văzut în blocul funcțional. O entitate declarată într-un bloc funcțional este văzută de la punctul de declarație până la sfârșitul blocului funcțional. Următorul program scurt ilustrează acest lucru:

#include
#include
folosind spațiu de numeore;

coarda fn(str str)
{
charstri[] = „banane”;
/ * alte afirmații * /
șir totalStr=str+stri;
întoarceretotalStr;
}

intprincipal()
{
șir totStr=fn('mâncând ');
cost<<totStr<<' n';

întoarcere 0;
}

Ieșirea este:
mâncând banane

Notă: O entitate declarată în afara funcției (deasupra acesteia) poate fi văzută în lista parametrilor funcției și, de asemenea, în blocul funcțional.

Eticheta

Scopul unei etichete este funcția în care apare. Următorul cod ilustrează acest lucru:

#include
folosind spațiu de numeore;

nulfn()
{
mergi lalabl;
/ * alte afirmații * /
labl: intnu= 2;
cost<<nu<<' n';
}

intprincipal()
{
fn();

întoarcere 0;
}

Ieșirea este 2.

Domeniul enumerării

Enumerare fără scop
Luați în considerare următorul bloc if:

dacă (1==1)
{
enum {a, b, c=b+2};
cost<<la<<''<<b<<''<<c<<' n';
}

Ieșirea este 0 1 3.

Prima linie din bloc este o enumerare, a, b și c sunt enumeratorii săi. Domeniul de aplicare al unui enumerator începe de la punctul de declarație până la sfârșitul blocului de anexare al enumerării.

Următoarea declarație nu se va compila, deoarece punctul de declarație al lui c este după cel al lui a:

enum {la=c+2, b, c};

Următorul segment de cod nu se va compila deoarece enumeratoarele sunt accesate după blocul de anexare al enumerării:

dacă (1==1)
{
enum {a, b, c=b+2};
}
cost<<la<<''<<b<<''<<c<<' n'; // eroare: în afara scopului

Enumerarea de mai sus este descrisă ca o enumerare fără scop, iar enumeratorii săi sunt descriși ca enumeratori fără scop. Acest lucru se datorează faptului că începe doar cu cuvântul rezervat, enum. Enumerările care încep cu enum class sau enum struct sunt descrise ca enumerări cu scop. Enumeratorii lor sunt descriși ca enumeratori cu scop.

Enumerare acoperită
Următoarea afirmație este OK:

enum clasămasculin{a, b, c=b+2};

Acesta este un exemplu de enumerare cu scop. Numele clasei este nam. Aici, domeniul de aplicare al enumeratorului începe de la punctul de declarație până la sfârșitul definiției de enumerare, și nu la sfârșitul blocului de anexare pentru enumerare. Următorul cod nu se va compila:

dacă (1==1)
{
enum clasămasculin{a, b, c=b+2};
cost<<la<<''<<b<<''<<c<<' n'; // eroare: în afara scopului pentru clasa enum sau struct enum
}

Domeniul de aplicare al clasei

Cu scop normal, regiunea declarativă începe dintr-un punct, apoi continuă și se oprește într-un punct diferit. Domeniul de aplicare există într-o regiune continuă. Cu clasa, scopul unei entități poate fi în diferite regiuni care nu sunt unite. Regulile pentru blocurile imbricate se aplică în continuare. Următorul program ilustrează acest lucru:

#include
folosind spațiu de numeore;

// Clasa de bază
clasăCla
{
privat:
intmemP= 5;
protejat:
intmemPro= 9;
public:
nulfn()
{
cost<<memP<<' n';
}
};

// Clasa derivată
clasăDerCla: publicCla
{
public:
intderMem=memPro;
};
intprincipal()
{
Cla obj;
obiect.fn();
DerCla derObj;
cost<<derObj.derMem<<' n';

întoarcere 0;
}

Ieșirea este:
5
9

În clasa Cla, variabila memP, este văzută la punctul de declarație. După aceea, porțiunea scurtă de protejat este omisă, apoi văzută din nou în blocul funcțional membru al clasei. Clasa derivată este omisă, apoi văzută din nou la sfera funcției main () (bloc).

În clasa Cla, variabila memPro, este văzută la punctul de declarație. Porțiunea funcției publice fn () este omisă, apoi văzută în blocul de descriere a clasei derivate. Este văzut din nou în jos în funcția main ().

Operator rezoluție domeniu
Operatorul de rezoluție a domeniului în C ++ este ::. Este folosit pentru a accesa un membru static al clasei. Următorul program ilustrează acest lucru:

#include
folosind spațiu de numeore;

clasăCla
{
public:
static int consteu eu= 5;
public:
static nulfn()
{
cost<<eu eu<<' n';
}
};
intprincipal()
{
cost<<Cla::eu eu<<' n';
Cla::fn();

întoarcere 0;
}

Ieșirea este:
5
5

Membrii statici sunt văzuți în blocul funcțional main (), accesat utilizând operatorul de rezoluție a scopului.

Scopul parametrilor șablonului

Domeniul de aplicare normal al unui nume de parametru șablon începe de la punctul de declarație până la sfârșitul blocului său, ca în codul următor:

șablon<typenameT,typenameU> structVârste
{
T John= unsprezece;
Tu Peter= 12.3;
T Maria= 13;
U Bucuria= 14.6;
};

U și T sunt văzute în interiorul blocului.

Pentru un prototip de funcție șablon, domeniul de aplicare începe de la punctul de declarație până la sfârșitul listei de parametri a funcției, ca în următoarea declarație:

șablon<typenameT,typenameU> nulfunc(Tu nu, u cha,const char *str);

Cu toate acestea, când vine vorba de descrierea clasei (definiție), domeniul de aplicare poate fi, de asemenea, de porțiuni diferite, ca în următorul cod:

#include
folosind spațiu de numeore;

șablon<clasăT,clasăU> clasăTheCla
{
public:
t num;
staticU ch;

nulfunc(Tată,const char *str)
{
cost << 'Sunt ' <<pe unu<< „cărți care merită” <<Nu<<str<< ' in magazin.' << ' n';
}
static nuldistracţie(U ch)
{
dacă (cap== 'la')
cost << „Funcția oficială de membru static” << ' n';
}
};

intprincipal()
{
TheCla<int,char>obiect;
obiect.pe unu = 12;
obiect.func(„$”,„500”);

întoarcere 0;
}

Nume Ascundere

Un exemplu de ascundere a numelui apare atunci când numele aceluiași tip de obiect este re-declarat într-un bloc imbricat. Următorul program ilustrează acest lucru:

#include
folosind spațiu de numeore;

nulfn()
{
intUnde= 3;
dacă (1==1)
{
intUnde= 4;
cost<<Unde<<' n';
}
cost<<Unde<<' n';
}

intprincipal()
{
fn();
întoarcere 0;
}

Ieșirea este:
4
3

Acest lucru se datorează faptului că var în blocul imbricat a ascuns var în blocul exterior.

Posibilitatea repetării declarației în același domeniu

Declarația este punctul în care numele este introdus (pentru prima dată) în domeniul său de aplicare.

Prototipul funcției
Diferite entități, chiar de diferite tipuri, nu pot fi declarate în mod normal în același domeniu. Cu toate acestea, un prototip de funcție poate fi declarat de mai multe ori în același scop. Următorul program cu două prototipuri de funcții și definiția funcției corespunzătoare ilustrează acest lucru:

#include
folosind spațiu de numeore;

nulfn(intpe unu);
nulfn(intpe unu);

nulfn(intpe unu)
{
cost<<pe unu<<' n';
}

intprincipal()
{
fn(5);

întoarcere 0;
}

Programul funcționează.

Funcții supraîncărcate
Funcțiile supraîncărcate sunt funcții cu același nume, dar semnături de funcții diferite. Ca o altă excepție, funcțiile supraîncărcate cu același nume pot fi definite în același domeniu. Următorul program ilustrează acest lucru:

#include
folosind spațiu de numeore;

nulfn(intpe unu)
{
cost<<pe unu<<' n';
}

nulfn(plutiNu)
{
cost<<Nu<<' n';
}

intprincipal()
{
fn(5);
plutiflt= 8.7;
fn(flt);

întoarcere 0;
}

Ieșirea este:
5
8.7

Funcțiile supraîncărcate au fost definite în domeniul global.

Domeniul de aplicare al spațiului de nume

Scopul spațiului de nume merită propriul articol. Articolul menționat a fost scris pentru acest site, linuxhint.com. Tastați doar cuvintele de căutare Spațiul de nume Domeniu în caseta de căutare a acestui site (pagina) și faceți clic pe OK și veți primi articolul.

Domeniul de aplicare în diferite porțiuni

Clasa nu este singura schemă în care domeniul de aplicare poate fi în porțiuni diferite. Specificatorul prietenului, anumite utilizări ale specificatorului de tip elaborat și directivele de utilizare sunt alte scheme în care domeniul de aplicare se află în locuri diferite - pentru detalii, vezi mai târziu.

Concluzie

Un domeniu de aplicare este o regiune declarativă. O regiune declarativă este cea mai mare parte a textului programului în care numele unei entități este valid. Poate fi împărțit în mai multe porțiuni în conformitate cu anumite scheme de programare, cum ar fi blocurile imbricate. Porțiunile care nu au punctul de declarație formează domeniul de aplicare potențial. Scopul potențial poate avea sau nu declarația.