CV staat voor Constant-Volatile. De declaratie van een object dat niet wordt voorafgegaan door const en/of vluchtig is een cv-ongekwalificeerd type. Aan de andere kant is de declaratie van een object dat wordt voorafgegaan door const en/of vluchtig een cv-gekwalificeerd type. Als een object const is gedeclareerd, kan de waarde op zijn locatie niet worden gewijzigd. Een vluchtige variabele is een variabele waarvan de waarde onder invloed staat van de programmeur en daarom niet kan worden gewijzigd door de compiler.Opslagklassespecificaties verwijzen naar het leven, de plaats en de manier waarop een type bestaat. Specificatie van opslagklassen is statisch, veranderlijk, thread_local en extern.
Dit artikel legt C++-kwalificaties en opslagklassespecificaties uit. Dus enige voorkennis in C++ is handig om het artikel echt te waarderen.
Artikel Inhoud:
- Kwalificaties
- Specificatie van opslagklasse
- Conclusie
Kwalificaties:
const
Een object dat constant wordt verklaard, is een object waarvan de opslag (locatie) niet kan worden gewijzigd. Bijvoorbeeld in de verklaring:
int const theInt = 5;De waarde van 5 in de opslag voor theInt kan niet worden gewijzigd.
vluchtig
Denk aan de volgende stelling:
int poortwaarde = 26904873;Compilers bemoeien zich soms met de waarde van een variabele in de hoop het programma te optimaliseren. De compiler kan de waarde van een variabele constant houden als het niet de bedoeling is constant te zijn. Objectwaarden die te maken hebben met memory-mapped IO-poorten, of Interrupt Service Routines van randapparatuur, kunnen door de compiler worden verstoord. Om dergelijke interferentie te voorkomen, maakt u de variabele vluchtig, zoals:
int vluchtige portVal;poortwaarde = 26904873;
of zoals:
int vluchtige portVal = 26904873;
Const en vluchtig combineren:
const en vluchtig kunnen als volgt in één verklaring voorkomen:
int const vluchtige portVal = 26904873;cv-kwalificaties
Een variabele voorafgegaan door const en/of vluchtig is een cv-gekwalificeerd type. Een variabele die niet wordt voorafgegaan door const of volatiel of beide is een cv-ongekwalificeerd type.
Bestellen:
Het ene type kan meer cv-gekwalificeerd zijn dan het andere:
- Geen enkele cv-kwalificatie is minder dan een const-kwalificatie
- Geen enkele cv-kwalificatie is ook minder dan een vluchtige kwalificatie
- Geen enkele cv-kwalificatie is minder dan een const-vluchtige kwalificatie
- const-kwalificatie is minder dan een const-vluchtige kwalificatie
- vluchtige kwalificatie is minder dan een const-vluchtige kwalificatie
Het is nog niet vastgesteld of const en vluchtig van dezelfde rang zijn.
Array en geïnstantieerd object:
Wanneer een array constant wordt verklaard, zoals in de volgende instructie, betekent dit dat de waarde van elk element van de array niet kan worden gewijzigd:
const char arr[] = 'a', 'b', 'c', 'd';Of het nu een 'a', 'b', 'c' of 'd' is, het kan nog steeds niet worden gewijzigd in een andere waarde (teken).
Een vergelijkbare situatie is van toepassing op een geïnstantieerd object van een klasse. Denk aan het volgende programma:
#includenamespace std; gebruiken;
klasse Cla
openbaar:
char ch0 = 'a';
char ch1 = 'b';
char ch2 = 'c';
char ch3 = 'd';
;
int hoofd()
const Cla obj;
retourneer 0;
Vanwege de verklaring "const Cla obj;" met const in de functie main() kan noch 'a' noch 'b' noch 'c' of 'd' worden gewijzigd in een andere waarde.
Specificatie van opslagklassen:
Specificatie van opslagklassen is statisch, veranderlijk, thread_local en extern.
De statische opslagklasse-specificatie
De specificatie van de statische opslagklasse zorgt ervoor dat de variabele kan leven nadat het bereik is doorlopen, maar kan niet rechtstreeks worden geopend.
Het volgende programma illustreert dit, met een recursieve functie:
#includenamespace std; gebruiken;
int-functie()
statisch int stac = 10;
cout << stac < 50)
cout << '\n';
retourneer 0;
functie();
int hoofd()
functie();
retourneer 0;
De uitvoer is:
10 20 30 40 50Als een statische variabele niet wordt geïnitialiseerd bij de eerste declaratie, neemt deze de standaardwaarde voor zijn type aan.
De statische specificatie kan ook worden gebruikt met leden van een klasse; het gebruik hier is anders. Hier kan het lid worden geopend zonder instantie voor het object.
Het volgende programma illustreert dit voor een gegevenslid:
#includenamespace std; gebruiken;
klasse Cla
openbaar:
statische const int num = 8;
;
int hoofd()
cout << Cla::num << '\n';
retourneer 0;
De uitvoer is:
8Het statische gegevenslid moet constant zijn. Merk op dat het gebruik van de scope resolutie-operator om toegang te krijgen tot de statische variabele buiten het bereik (in de hoofdfunctie).
Het volgende programma illustreert het gebruik van "statisch" voor een lidfunctie:
#includenamespace std; gebruiken;
klasse Cla
openbaar:
statische ongeldige methode ()
cout << "Of static member function!" << '\n';
;
int hoofd()
Kla::methode();
retourneer 0;
De uitvoer is:
Van statische lidfunctie!
Merk op dat het gebruik van de scope resolutie-operator om toegang te krijgen tot de statische lidfunctie buiten het bereik (in de hoofdfunctie).
De veranderlijke specificatie
Onthoud van bovenaf dat als een geïnstantieerd object begint met const, de waarde van een van zijn normale gegevensleden niet kan worden gewijzigd. En om een dergelijk gegevenslid te wijzigen, moet het worden gedeclareerd, veranderlijk.
Het volgende programma illustreert dit:
#includenamespace std; gebruiken;
klasse Cla
openbaar:
char ch0 = 'a';
char ch1 = 'b';
veranderlijk char ch2 = 'c';
char ch3 = 'd';
;
int hoofd()
const Cla obj;
obj.ch2 = 'z';
cout << obj.ch0 << " << obj.ch1 << " << obj.ch2 << " << obj.ch3 << " << '\n';
retourneer 0;
De uitvoer is:
'a'b'z'd'De thread_local specificatie
Bij de normale uitvoering van een programma wordt het ene codesegment uitgevoerd, dan het volgende codesegment, gevolgd door een ander codesegment, enzovoort. Dat is één draad; de rode draad. Als twee codesegmenten tegelijkertijd worden uitgevoerd (dezelfde duur), is een tweede thread nodig. Het resultaat van de tweede thread kan zelfs klaar zijn voor de hoofdthread.
De functie main() is als de hoofdthread. Een programma kan meer dan twee threads hebben voor zo'n asynchroon gedrag.
De tweede thread heeft een scope (block scope) nodig om te kunnen werken. Dit wordt meestal geleverd door het functiebereik, een functie. Een variabele in een outer scope die te zien is in de scope van de tweede thread.
Het volgende korte programma illustreert het gebruik van de specificatie thread_local:
#include#include
namespace std; gebruiken;
thread_local int inter = 1;
ongeldige thread_function()
tussen = tussen + 1;
cout << inter << "nd thread\n";
int hoofd()
thread thr(&thread_function); // thr begint te lopen
cout << inter << "st or main thread\n";
door.meedoen(); // hoofdthread wacht op de thread, thr om te voltooien
retourneer 0;
De uitvoer is:
1e of hoofddraad2e draad
De variabele inter, voorafgegaan door thread_local, betekent dat inter een aparte instantie heeft in elke thread. En dat het in verschillende threads kan worden gewijzigd om verschillende waarden te hebben. In dit programma wordt de waarde toegewezen, 1 in de hoofdthread, en gewijzigd naar de waarde, 2 in de tweede thread.
Een thread heeft een speciaal object nodig om te kunnen werken. Voor dit programma is de bibliotheek opgenomen door “#include
De join()-lidfunctie voor het speciale object, op de gebruikte positie, laat de hoofdthread wachten tot de tweede thread klaar is met uitvoeren voordat deze verder wordt uitgevoerd, anders kan de main()-functie afsluiten zonder dat de (tweede) thread leverde zijn resultaat op.
De externe specificatie
Simpel gezegd, voor een declaratie wordt geen geheugen toegewezen voor de variabele of functie, terwijl voor een definitie geheugen wordt toegewezen. Met het extern gereserveerde woord kan een globale variabele of functie in het ene bestand worden gedeclareerd, maar in een ander worden gedefinieerd. Dergelijke bestanden worden vertaaleenheden genoemd voor de volledige C++-toepassing.
Typ het volgende programma en sla het op met de bestandsnaam mainFile:
#includenamespace std; gebruiken;
int mijnInt;
const char;
ongeldig myFn();
int hoofd()
mijnFn();
retourneer 0;
De variabele myInt, de constante variabele ch en de functie myFn(), zijn gedeclareerd zonder gedefinieerd te zijn.
Typ het volgende programma met de definities en sla het op met de bestandsnaam, otherFile, in dezelfde map:
#includenamespace std; gebruiken;
int mijnInt = 10;
const char ch = 'c';
ongeldig mijnFn()
cout << "myFn() says " << myInt << " and " << ch <<'\n';
Probeer de toepassing op de terminal (DOS-opdrachtprompt) te compileren met de volgende opdracht en merk op dat deze mogelijk niet compileert:
g++ hoofdbestand.cpp ander bestand.cpp -o voltooid.exeLaat nu de drie declaraties in mainFile voorafgaan met het woord "extern", als volgt:
extern int mijnInt;externe const char ch;
extern ongeldig myFn();
Hoofdbestand opnieuw opslaan. Stel de aanvraag samen met:
g++ hoofdbestand.cpp ander bestand.cpp -o voltooid.exe(Zo worden aparte bestanden voor dezelfde applicatie gecompileerd in C++)
En het zou moeten compileren. Voer nu de applicatie uit, voltooi.exe, en de uitvoer zou moeten zijn:
myFn() zegt 10 en cMerk op dat met het gebruik van "extern", een constante variabele in één bestand kan worden gedeclareerd, maar in een ander kan worden gedefinieerd. Bij het omgaan met functiedeclaratie en definitie in verschillende bestanden, is het gebruik van extern optioneel.
Wanneer extern gebruiken?? Gebruik het als je geen header-bestanden met globale declaraties hebt.
"extern" wordt ook gebruikt met sjabloondeclaraties - zie later.
Conclusie:
Een variabele voorafgegaan door const en/of vluchtig is een cv-gekwalificeerd type. Een variabele, niet voorafgegaan door const of volatiel of beide, is een cv-ongekwalificeerd type.
Specificatie van opslagklassen is statisch, veranderlijk, thread_local en extern. Deze hebben invloed op de levensduur (duur), plaats en manier van werken van variabelen in een applicatie.