Bereik in C++

Scope C



Een entiteit in C++ heeft een naam die gedeclareerd en/of gedefinieerd kan worden. Een aangifte is een definitie, maar een definitie is niet per se een aangifte. Een definitie wijst geheugen toe aan de benoemde entiteit, maar een declaratie kan al dan niet geheugen toewijzen aan de benoemde entiteit. Een declaratief gebied is het grootste deel van een programma waarin de naam van een entiteit (variabele) geldig is. Dat gebied wordt een bereik of een potentieel bereik genoemd. In dit artikel wordt scoping in C++ uitgelegd. Verder is basiskennis van C++ nodig om dit artikel te begrijpen.

Artikel Inhoud

Declaratieve regio en reikwijdte

Een declaratief gebied is het grootste deel van een programmatekst waarin de naam van een entiteit geldig is. Het is de regio waarin de ongekwalificeerde naam kan worden gebruikt (gezien) om naar dezelfde entiteit te verwijzen. Beschouw het volgende korte programma:







#erbij betrekken
gebruik makend van naamruimteuur;

leegtefn()
{
intwaar= 3;
indien (1==1)
{
kosten<<waar<<'N';
}
}

inthoofd()
{
fn();
opbrengst 0;
}

De functie fn() heeft twee blokken: een binnenblok voor de if-conditie en een buitenste blok voor de functiebody. De identifier, var, wordt geïntroduceerd en gezien in het buitenste blok. Het is ook te zien in het binnenste blok, met de cout-verklaring. De buitenste en binnenste blokken zijn beide het toepassingsgebied voor de naam, var.



De naam, var, kan echter nog steeds worden gebruikt om een ​​andere entiteit te declareren, zoals een float in het binnenste blok. De volgende code illustreert dit:



#erbij betrekken
gebruik makend van naamruimteuur;

leegtefn()
{
intwaar= 3;
indien (1==1)
{
vlotwaar= 7,5;
kosten<<waar<<'N';
}
}

inthoofd()
{
fn();
opbrengst 0;
}

De uitvoer is 7,5. In dit geval kan de naam var niet langer worden gebruikt in het binnenste blok om te verwijzen naar het gehele getal van waarde 3, dat in het buitenste blok werd geïntroduceerd (gedeclareerd). Dergelijke binnenblokken worden potentiële ruimte genoemd voor entiteiten die in het buitenblok zijn aangegeven.





Opmerking: Een entiteit van hetzelfde type, zoals die van het buitenste blok, kan nog steeds worden gedeclareerd in het binnenste blok. In dit geval is wat echter geldig is in het binnenste blok de nieuwe verklaring en zijn betekenis, terwijl de oude verklaring en zijn betekenis buiten het binnenste blok geldig blijven in het buitenste blok.

Een declaratie met dezelfde naam in een binnenblok overschrijft normaal gesproken de verklaring met dezelfde naam buiten dat binnenblok. Binnenblokken kunnen andere binnenblokken nesten.



Wereldwijd bereik

Wanneer een programmeur net begint met het typen van een bestand, is dat het globale bereik. Het volgende korte programma illustreert dit:

#erbij betrekken
gebruik makend van naamruimteuur;

vlotwaar= 9.4;

inthoofd()
{
kosten <<waar<<'N';
kosten <<::waar<<'N';

opbrengst 0;
}

De uitvoer is:
9.4
9.4

In dit geval begint het declaratieve gebied of bereik voor var vanaf het declaratiepunt voor var en gaat het verder naar beneden tot het einde van het bestand (vertaaleenheid).

Het blok van de functie main() is een ander bereik; het is een geneste scope voor de globale scope. Om toegang te krijgen tot een entiteit van het globale bereik, vanuit een ander bereik, wordt de identifier rechtstreeks gebruikt of voorafgegaan door de operator voor bereikomzetting, :: .

Opmerking: De entiteit, main(), wordt ook gedeclareerd in het globale bereik.

Bereik blokkeren

De instructie if, while, do, for of switch kan elk een blok definiëren. Een dergelijke verklaring is een samengestelde verklaring. De naam van een variabele die in een blok is gedeclareerd, heeft het bereik van een blok. Het toepassingsgebied begint op het punt van declaratie en eindigt aan het einde van het blok. Het volgende korte programma illustreert dit voor de variabele ident:

#erbij betrekken
gebruik makend van naamruimteuur;

inthoofd()
{
indien (1==1)
{
/*sommige uitspraken*/
intident= 5;
kosten<<ident<<'N';
/*sommige uitspraken*/
}
opbrengst 0;
}

Een variabele, zoals ident, gedeclareerd bij block scope is een lokale variabele.

Een variabele die buiten het blokbereik en daarboven is gedeclareerd, is te zien in de kop van het blok (bijv. voorwaarde voor als-blok) en ook binnen het blok. Het volgende korte programma illustreert dit voor de variabele identif:

#erbij betrekken
gebruik makend van naamruimteuur;

inthoofd()
{
intidentif= 8;

indien (identif== 8)
{
kosten<<identif<<'N';
}
opbrengst 0;
}

De uitvoer is 8. Er zijn hier twee blokbereiken: het blok voor de functie main() en de geneste if-compound-instructie. Het geneste blok is het potentiële bereik van het functieblok main().

Een declaratie die in een blokscope is geïntroduceerd, kan niet buiten het blok worden gezien. Het volgende korte programma, dat niet compileert, illustreert dit met de variabele variab:

#erbij betrekken
gebruik makend van naamruimteuur;

inthoofd()
{
indien (1 == 1)
{
intvariabel= vijftien;
}
kosten<<variabel<<'N'; //fout: toegankelijk buiten het bereik.

opbrengst 0;
}

De compiler produceert een foutmelding voor variab.

Een geïntroduceerde entiteit, gedeclareerd in de kop van een samengestelde functie, kan niet worden gezien buiten (onder) de samengestelde instructie. De volgende for-loop-code kan niet worden gecompileerd, wat resulteert in een foutmelding:

#erbij betrekken
gebruik makend van naamruimteuur;

inthoofd()
{
voor (intl=0;l<4; ++l)
{
kosten<<l<<'';
}
kosten<<l<<'';

opbrengst 0;
}

De iteratievariabele, i, wordt binnen het for-loop-blok gezien, maar niet buiten het for-loop-blok.

Functieomvang:

Een functieparameter is te zien in het functieblok. Een entiteit gedeclareerd in een functieblok wordt gezien vanaf het punt van declaratie tot het einde van het functieblok. Het volgende korte programma illustreert dit:

#erbij betrekken
#erbij betrekken
gebruik makend van naamruimteuur;

tekenreeks fn(tekenreeks)
{
chargestreept[] = 'bananen';
/*andere verklaringen*/
tekenreeks totaalStr=P+gestreept;
opbrengsttotaalStr;
}

inthoofd()
{
string totStr=fn('aan het eten ');
kosten<<totStr<<'N';

opbrengst 0;
}

De uitvoer is:
bananen eten

Opmerking: Een entiteit die buiten de functie (hierboven) is gedeclareerd, is te zien in de lijst met functieparameters en ook in het functieblok.

Label

Het bereik van een label is de functie waarin het verschijnt. De volgende code illustreert dit:

#erbij betrekken
gebruik makend van naamruimteuur;

leegtefn()
{
ga naarlabl;
/*andere verklaringen*/
labl: intniet= 2;
kosten<<niet<<'N';
}

inthoofd()
{
fn();

opbrengst 0;
}

De uitvoer is 2.

Opsommingsbereik

Telling zonder scope
Overweeg het volgende if-blok:

indien (1==1)
{
opsomming {a, b, c=B+2};
kosten<<tot<<''<<B<<''<<C<<'N';
}

De uitvoer is 0 1 3.

De eerste regel in het blok is een opsomming, a, b en c zijn de tellers. De reikwijdte van een enumerator begint vanaf het punt van declaratie tot het einde van het omsluitende blok van de opsomming.

De volgende verklaring wordt niet gecompileerd omdat het declaratiepunt van c na dat van a ligt:

opsomming {tot=C+2, b, c};

Het volgende codesegment wordt niet gecompileerd omdat de enumerators worden geopend na het omsluitende blok van de opsomming:

indien (1==1)
{
opsomming {a, b, c=B+2};
}
kosten<<tot<<''<<B<<''<<C<<'N'; //fout: buiten bereik

De bovenstaande opsomming wordt beschreven als een opsomming zonder scope, en de enumerators worden beschreven als enumerators zonder scope. Dit komt omdat het alleen begint met het gereserveerde woord enum. Opsommingen die beginnen met enum class of enum struct worden beschreven als scoped opsommingen. Hun enumerators worden beschreven als scoped enumerators.

Scoped opsomming
De volgende stelling is oké:

opsomming klasmannelijk{a, b, c=B+2};

Dit is een voorbeeld van een scoped enumeratie. De naam van de klas is nam. Hier begint het bereik van de enumerator vanaf het punt van declaratie tot het einde van de opsommingsdefinitie, en niet het einde van het omsluitende blok voor de opsomming. De volgende code wordt niet gecompileerd:

indien (1==1)
{
opsomming klasmannelijk{a, b, c=B+2};
kosten<<tot<<''<<B<<''<<C<<'N'; // fout: buiten bereik voor enum class of enum struct
}

Klassebereik

Bij normale scoping begint het declaratieve gebied vanaf een punt, gaat dan verder en stopt op een ander punt. De scope bestaat in één aaneengesloten regio. Met de klasse kan het bereik van een entiteit zich in verschillende regio's bevinden die niet zijn samengevoegd. De regels voor geneste blokken zijn nog steeds van toepassing. Het volgende programma illustreert dit:

#erbij betrekken
gebruik makend van naamruimteuur;

//Basisklasse
klasCla
{
privaat:
intmemP= 5;
beschermd:
intmemPro= 9;
openbaar:
leegtefn()
{
kosten<<memP<<'N';
}
};

//Afgeleide klasse
klasDerCla: openbaarCla
{
openbaar:
intderMem=memPro;
};
inthoofd()
{
Cla obj;
obj.fn();
DerCla derObj;
kosten<<derObj.derMem<<'N';

opbrengst 0;
}

De uitvoer is:
5
9

In de klasse Cla, de variabele memP, wordt gezien op het punt van declaratie. Daarna wordt het korte gedeelte van beschermd overgeslagen en vervolgens opnieuw gezien in het functieblok van het klasselid. De afgeleide klasse wordt overgeslagen en vervolgens opnieuw gezien in het functiebereik (blok) main().

In de klasse Cla wordt de variabele memPro gezien op het punt van declaratie. Het gedeelte van de openbare functie fn() wordt overgeslagen en wordt vervolgens weergegeven in het afgeleide klassebeschrijvingsblok. Het wordt opnieuw weergegeven in de functie main().

Scope Resolutie Operator
De operator voor bereikresolutie in C++ is :: . Het wordt gebruikt om toegang te krijgen tot een statisch lid van de klas. Het volgende programma illustreert dit:

#erbij betrekken
gebruik makend van naamruimteuur;

klasCla
{
openbaar:
statisch int constmeme= 5;
openbaar:
statisch leegtefn()
{
kosten<<meme<<'N';
}
};
inthoofd()
{
kosten<<Cla::meme<<'N';
Cla::fn();

opbrengst 0;
}

De uitvoer is:
5
5

De statische leden worden weergegeven in het functieblok main(), dat toegankelijk is met behulp van de scope-resolutie-operator.

Bereik van sjabloonparameter

Het normale bereik van een sjabloonparameternaam begint vanaf het declaratiepunt tot het einde van het blok, zoals in de volgende code:

sjabloon<typenaamT,typenaamu> structurerenleeftijden
{
T John= elf;
U Peter= 12.3;
T Mary= 13;
Jij Vreugde= 14.6;
};

U en T worden binnen het blok gezien.

Voor een prototype van een sjabloonfunctie begint het bereik vanaf het declaratiepunt tot het einde van de functieparameterlijst, zoals in de volgende instructie:

sjabloon<typenaamT,typenaamu> leegtefunctie(Jij nee, jij cha,const char *P);

Als het echter gaat om de klassebeschrijving (definitie), kan het bereik ook uit verschillende delen bestaan, zoals in de volgende code:

#erbij betrekken
gebruik makend van naamruimteuur;

sjabloon<klasT,klasu> klasDe Cla
{
openbaar:
t aantal;
statischu ch;

leegtefunctie(jij vader,const char *P)
{
kosten << 'Er zijn ' <<op een<< 'boeken waard' <<Nee<<P<< ' in de winkel.' << 'N';
}
statisch leegteplezier(u ch)
{
indien (ch== 'tot')
kosten << 'Officiële statische ledenfunctie' << 'N';
}
};

inthoofd()
{
De Cla<int,char>obj;
obj.op een = 12;
obj.functie('$','500');

opbrengst 0;
}

Naam verbergen

Een voorbeeld van naam verbergen doet zich voor wanneer de naam van hetzelfde objecttype opnieuw wordt gedeclareerd in een genest blok. Het volgende programma illustreert dit:

#erbij betrekken
gebruik makend van naamruimteuur;

leegtefn()
{
intwaar= 3;
indien (1==1)
{
intwaar= 4;
kosten<<waar<<'N';
}
kosten<<waar<<'N';
}

inthoofd()
{
fn();
opbrengst 0;
}

De uitvoer is:
4
3

Het is omdat var in het geneste blok var in het buitenste blok verborg.

Mogelijkheid om aangifte in hetzelfde bereik te herhalen

Het punt van de aangifte is waar de naam (voor het eerst) in zijn toepassingsgebied wordt geïntroduceerd.

Functie Prototype:
Verschillende entiteiten, zelfs van verschillende typen, kunnen normaal gesproken niet binnen hetzelfde toepassingsgebied worden gedeclareerd. Een functie-prototype kan echter meer dan eens in hetzelfde bereik worden gedeclareerd. Het volgende programma met twee functie-prototypes en bijbehorende functiedefinitie illustreert dit:

#erbij betrekken
gebruik makend van naamruimteuur;

leegtefn(intop een);
leegtefn(intop een);

leegtefn(intop een)
{
kosten<<op een<<'N';
}

inthoofd()
{
fn(5);

opbrengst 0;
}

Het programma werkt.

Overbelaste functies
Overbelaste functies zijn functies met dezelfde naam maar verschillende functiesignaturen. Als een andere uitzondering kunnen overbelaste functies met dezelfde naam in hetzelfde bereik worden gedefinieerd. Het volgende programma illustreert dit:

#erbij betrekken
gebruik makend van naamruimteuur;

leegtefn(intop een)
{
kosten<<op een<<'N';
}

leegtefn(vlotNee)
{
kosten<<Nee<<'N';
}

inthoofd()
{
fn(5);
vlotflt= 8.7;
fn(flt);

opbrengst 0;
}

De uitvoer is:
5
8.7

De overbelaste functies zijn gedefinieerd in de globale scope.

Naamruimtebereik

Namespace Scope verdient een eigen artikel. Het genoemde artikel is geschreven voor deze website, linuxhint.com. Typ gewoon de zoekwoorden Namespace Scope in het zoekvak van deze site (pagina) en klik op OK, en u krijgt het artikel.

Bereik in verschillende porties

De klasse is niet het enige schema waarbij het bereik in verschillende delen kan zijn. Friend-specificatie, bepaalde toepassingen van de uitgewerkte-type-specificatie en gebruiksrichtlijnen zijn andere schema's waarbij het toepassingsgebied zich op verschillende plaatsen bevindt - zie later voor details.

Conclusie

Een scope is een declaratief gebied. Een declaratief gebied is het grootste deel van een programmatekst waarin de naam van een entiteit geldig is. Het kan in meer dan één gedeelte worden verdeeld in overeenstemming met bepaalde programmeerschema's, zoals geneste blokken. De gedeelten die het declaratiepunt niet hebben, vormen de potentiële scope. De potentiële reikwijdte kan al dan niet de verklaring hebben.