C++

Objectlevensduur en opslagduur in C++

Objectlevensduur en opslagduur in C++
Bij het maken van een object moet de locatie in het geheugen worden bepaald voordat het wordt geïnitialiseerd. Initialisatie betekent waarde toevoegen aan de locatie. De levensduur van een object begint net na initialisatie. Wanneer een object sterft, wordt de locatie (opslag), die het object bezette vrijgegeven en vervolgens wordt de computer afgesloten of wordt de opslagruimte ingenomen (gebruikt) door een ander object. Het vrijgeven van een opslagmiddel, het ongeldig maken van de identifier of aanwijzer die de opslag in beslag nam. De levensduur van een object eindigt wanneer de opslag wordt vrijgegeven.

Er is enige tijd nodig om een ​​object te maken. Er is enige tijd nodig om een ​​object te doden. Als we het over een object hebben, zijn er twee dingen bij betrokken: de locatie die de opslag is, en de waarde. De betekenis van levensduur en opslagduur zijn vergelijkbaar; maar de duur wordt meer gezien vanuit het oogpunt van de locatie dan vanuit het oogpunt van de waarde. De opslagduur is de tijd vanaf het moment dat een locatie aan een object wordt gekoppeld tot het moment waarop de locatie wordt losgekoppeld van het object.

De rest van dit artikel illustreert de levensduur van het object en legt kort de verschillende opslagduur uit. U moet over basiskennis van C++ beschikken om dit artikel te begrijpen. Je moet ook kennis hebben van C++ scope.

Artikel Inhoud

Illustratie van de levensduur van objecten

Denk aan het volgende programma:

#include
namespace std; gebruiken;
int hoofd()

als (1 == 1)

int x;
x = 1;
char y;
y = 'A';
cout << x << y << '\n';

retourneer 0;

De uitgang is, 1A .

De levensduur van een object komt tot een einde wanneer het buiten het bereik valt. De levensduur van object x begint bij "x = 1;" en eindigt aan het einde van de if-local-scope. De levensduur van object y begint bij "y = 'A';" en eindigt aan het einde van de if-local-scope. Voordat beide objecten sterven, worden ze gebruikt in de cout-verklaring .

Opslagduur

De opslagduur wordt bepaald door een van de volgende schema's: automatische opslagduur; dynamische opslagduur; statische opslagduur; opslagduur thread thread. Opslagduurcategorieën, ook van toepassing op referenties.

Automatische opslagduur

Als een variabele niet expliciet als statisch, thread_local of extern is gedeclareerd, heeft die variabele een automatische opslagduur. Voorbeelden zijn x en y hierboven. De duur van dergelijke variabelen eindigt wanneer ze buiten het bereik vallen. Het volgende programma illustreert de automatische opslagduur voor een referentie en een pointer, in de globale scope.

#include
namespace std; gebruiken;
int x = 1;
int& m = x;
char y = 'A';
teken* n = &y;
int hoofd()

cout << m << *n << '\n';
retourneer 0;

De uitgang is, 1A .

De duur van m begint vanaf “int& m = x;” en eindigt aan het einde van het programma. De duur van n begint vanaf “char* n = &y;” en eindigt aan het einde van het programma.

Dynamische opslagduur

Gratis winkel

Op een moderne computer kan meer dan één programma tegelijkertijd worden uitgevoerd. Elk programma heeft zijn eigen geheugengedeelte. De rest van het geheugen dat door geen enkel programma wordt gebruikt, staat bekend als gratis opslag. De volgende uitdrukking wordt gebruikt om een ​​locatie terug te geven voor een geheel getal uit free store

nieuw int

Deze locatie (opslag) voor het geretourneerde gehele getal moet nog worden geïdentificeerd door toewijzing aan een pointer. De volgende code illustreert hoe u de aanwijzer gebruikt met gratis winkel:

int *ptrInt = nieuwe int;
*ptrInt = 12;
cout<< *ptrInt <<'\n';

De uitvoer is 12 .

Gebruik de delete-expressie als volgt om de levensduur van het object te beëindigen:

verwijder ptrInt;

Het argument voor de delete-expressie is een pointer. De volgende code illustreert het gebruik ervan:

int *ptrInt = nieuwe int;
*ptrInt = 12;
verwijder ptrInt;

Een aanwijzer die is gemaakt met de nieuwe uitdrukking en is verwijderd met de uitdrukking delete, heeft een dynamische opslagduur. Deze aanwijzer sterft als deze buiten bereik gaat, of wordt verwijderd. De duur van het object in de vorige code begint bij "*ptrInt = 12;" en eindigt aan het einde van het declaratieve gebied (scope). Er is meer aan de nieuwe en verwijderde uitdrukkingen dan hier is besproken - zie later.

Statische opslagduur

Statisch object

Een object dat statisch is verklaard, gedraagt ​​zich als het gewone object, behalve dat de opslagduur begint vanaf het moment dat het wordt geïnitialiseerd tot het einde van het programma. Het kan niet buiten zijn bereik worden gezien, maar het kan indirect van buiten zijn bereik worden gebruikt.

Beschouw het volgende programma, dat van 1 tot 5 moet tellen (test het programma niet):

#include
namespace std; gebruiken;
int fn()

int st = 1;
cout << " << stc;
stc = stc + 1;
als (stc > 5)
retourneer 0;
fn();

int hoofd()

fn();
retourneer 0;

De output is 1 1 1 1 1 1 1 1... en nooit echt eindigend. De functiedefinitie is een terugkerende functie; wat betekent dat het zichzelf blijft noemen totdat aan een voorwaarde is voldaan.

De oplossing is om het stc-object statisch te maken. Als een statisch object eenmaal is geïnitialiseerd, kan de waarde ervan niet worden gewijzigd totdat het programma is afgelopen. Het volgende programma (dat je kunt testen), dat hetzelfde is als het bovenstaande, maar nu met stc statisch gemaakt, telt van 1 tot 5 :

#include
namespace std; gebruiken;
int fn()

statische int stc = 1;
cout << " << stc;
stc = stk + 1;
als (stc > 5)
retourneer 0;
fn();

int hoofd()

fn();
retourneer 0;

De uitvoer is: 1 2 3 4 5 .

Opmerking: de duur van een statisch object begint wanneer het object is geïnitialiseerd en eindigt aan het einde van het programma. In de tussentijd kan het object indirect worden gebruikt, vanuit een ander bereik. Nadat een statisch object is geïnitialiseerd, kan de initiële waarde niet worden gewijzigd, zelfs niet als de definitie opnieuw wordt geëvalueerd. In de bovenstaande code wordt de stc niet gereset, de volgende keer dat deze wordt aangeroepen. De volgende keer dat het wordt aangeroepen, wordt het verhoogd met "stc = stc + 1;".

Statisch gegevenslid

Een set gerelateerde variabelen en functies kan in een gegeneraliseerde eenheid worden geplaatst die een klasse wordt genoemd. Als de variabelen bepaalde waarden krijgen, wordt de klasse een object. Een object wordt echter niet gemaakt door alleen waarden aan de variabele toe te kennen. De klasse wordt geïnstantieerd om een ​​object te verkrijgen; en elk gemaakt object heeft zijn eigen naam die verschilt van andere objecten van dezelfde klasse. Het volgende programma toont een klasse, genaamd TheCla en een object, genaamd obj; het laat ook zien hoe het object wordt geïnstantieerd en gebruikt in de functie main():

#include
namespace std; gebruiken;
klasse TheCla

openbaar:
int. aantal;
void func (char cha, const char *str)

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

;
int hoofd()

DeCla obj;
obj.aantal = 12;
obj.func('$', "500");
retourneer 0;

De uitvoer is:

Er zijn 12 boeken ter waarde van $500 in de winkel.

Merk op dat om de waarde van 12 aan de variabele num toe te kennen, het object moet worden geïnstantieerd voordat de toewijzing kan plaatsvinden. Het is mogelijk voor de programmeur om de waarde toe te wijzen zonder een object te instantiëren (creëren). Om dit te bereiken, moet de variabele num als statisch worden gedeclareerd. Vervolgens wordt het geopend als "TheCla::num" zonder de objectnaam, maar met de klassenaam. Het volgende programma illustreert dit:

#include
namespace std; gebruiken;
klasse TheCla

openbaar:
statische const int num = 12;
void func (char cha, const char *str)

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

;
int hoofd()

cout << TheCla::num << '\n';
DeCla obj;
obj.func('$', "500");
retourneer 0;

De uitvoer is:

12
Er zijn 12 boeken ter waarde van $500 in de winkel.

Merk op dat om toegang te krijgen tot het gegevenslid, num in main(), de scope-resolutie-operator, :: moest worden gebruikt. Ook niet dat de variabele num constant moest worden gemaakt en geïnitialiseerd in de klassebeschrijving (definitie).

Statische lidfunctie

Merk op dat in de vorige programmalijst hierboven, om de func-functie in main() te gebruiken, een object moest worden geïnstantieerd. Het is mogelijk voor de programmeur om de functie aan te roepen zonder een object te instantiëren (creëren). Om dit te bereiken, moet de functiedefinitie worden voorafgegaan door het woord "statisch". Vervolgens wordt het geopend als "TheCla::func()" zonder de objectnaam, maar met de klassenaam. Het volgende programma illustreert dit voor statische gegevenslid en statische lidfunctie:

#include
namespace std; gebruiken;
klasse TheCla

openbaar:
statische const int num = 12;
statische leegte func (char cha, const char *str)

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

;
int hoofd()

TheCla::func('$', "500");
retourneer 0;

De uitvoer is:

Er zijn 12 boeken ter waarde van $500 in de winkel.

Opslagduur van draad

Thread als een functie in C++, is nog niet geïmplementeerd door de g++-compiler. Dus in plaats van dit uit te leggen, wordt het citaat uit de C++-specificatie als volgt gegeven:

  1. Alle variabelen die zijn gedeclareerd met het trefwoord thread_local hebben een opslagduur voor threads. De opslag voor deze entiteiten zal duren voor de duur van de thread waarin ze zijn gemaakt. Er is een afzonderlijk object of verwijzing per thread, en het gebruik van de gedeclareerde naam verwijst naar de entiteit die is gekoppeld aan de huidige thread.
  2. Een variabele met een opslagduur voor threads moet worden geïnitialiseerd vóór het eerste gebruik en, indien geconstrueerd, worden vernietigd bij het verlaten van de thread.”

Conclusie

De levensduur van een object begint wanneer de initialisatie is voltooid en eindigt wanneer de opslag wordt vrijgegeven. Dynamische opslagduur begint wanneer de opslag die is gemaakt door (nieuw type) wordt geïnitialiseerd en eindigt wanneer het object buiten het bereik valt of wordt verwijderd door "delete pointer". De duur van een statisch object begint wanneer het object is geïnitialiseerd en eindigt aan het einde van het programma. Nadat een statisch object is geïnitialiseerd, kan de initiële waarde niet worden gewijzigd, zelfs niet als de definitie opnieuw wordt geëvalueerd. Statische gegevensleden en statische functieleden zijn toegankelijk buiten de klassebeschrijving met "ClassName::name".

Chrys

Cursor springt of beweegt willekeurig tijdens het typen in Windows 10
Als u merkt dat uw muiscursor vanzelf springt of beweegt, automatisch, willekeurig tijdens het typen op een Windows-laptop of -computer, dan kunnen en...
De scrollrichting van de muis en touchpads omkeren in Windows 10
Muis en Touchpads maken computergebruik niet alleen eenvoudig, maar ook efficiënter en minder tijdrovend. We kunnen ons een leven zonder deze apparate...
Hoe de muisaanwijzer en cursorgrootte, kleur en schema op Windows 10 te veranderen
De muisaanwijzer en cursor in Windows 10 zijn zeer belangrijke aspecten van het besturingssysteem. Dit geldt ook voor andere besturingssystemen, dus i...