Objektlebensdauer und Speicherdauer in C ++

Objektlebensdauer und Speicherdauer in C ++
Während des Erstellens eines Objekts muss sein Speicherort im Speicher festgelegt werden, bevor es initialisiert wird. Initialisierung bedeutet, Wert in den Standort zu setzen. Die Lebensdauer eines Objekts beginnt kurz nach der Initialisierung. Wenn ein Objekt stirbt, wird der Standort (Speicher), den das Objekt besetzt hat. Veröffentlichung eines Speichermittels, wodurch der Kennung oder Zeiger, der den Speicher besetzte, ungültig macht. Die Lebensdauer eines Objekts endet, wenn sein Speicher freigesetzt wird.

Es ist einige Zeit erforderlich, um ein Objekt zu erstellen. Es ist einige Zeit erforderlich, um ein Objekt zu töten. Wenn Sie über ein Objekt sprechen, sind zwei Dinge beteiligt: ​​der Ort, der der Speicher und der Wert ist. Die Bedeutung von Lebensdauer und Speicherdauer ist ähnlich; Die Dauer ist jedoch aus Sicht des Ortes mehr zu sehen als aus der Sicht des Wertes. Die Speicherdauer ist die Zeit, in der ein Objekt einem Objekt zu dem Zeitpunkt zugeordnet ist, an dem der Standort vom Objekt dissoziiert wird.

Der Rest dieses Artikels zeigt die Objektlebensdauer und erklärt kurz die verschiedenen Speicherdauer. Sie sollten Grundkenntnisse in C ++ haben, um diesen Artikel zu verstehen. Sie sollten auch Kenntnisse im C ++ - Scope haben.

Artikelinhalt

  • Illustration der Objektlebensdauer
  • Speicherdauer
  • Automatische Speicherdauer
  • Dynamische Speicherdauer
  • Statische Speicherdauer
  • Fadenspeicherdauer
  • Abschluss

Illustration der Objektlebensdauer

Betrachten Sie das folgende Programm:

#enthalten
Verwenden von Namespace STD;
int main ()

if (1 == 1)

int x;
x = 1;
Char y;
y = 'a';
Cout << x << y << '\n';

Rückkehr 0;

Die Ausgabe ist 1A .

Das Leben eines Objekts endet zu Ende, wenn es aus dem Zielfernrohr geht. Die Lebensdauer von Objekt X beginnt bei „x = 1“; und endet am Ende des IF-Lokal-Scope. Die Lebensdauer des Objekts y beginnt bei „y = 'a';“; und endet am Ende des IF-Lokal-Scope. Bevor beide Objekt sterben, werden sie in der Cout -Erklärung verwendet .

Speicherdauer

Die Speicherdauer wird durch eines der folgenden Schemata bestimmt: automatische Speicherdauer; dynamische Speicherdauer; statische Speicherdauer; Fadenspeicherdauer. Speicherdauerkategorien, auch für Referenzen gelten.

Automatische Speicherdauer

Wenn eine Variable, nicht explizit als statisch, thread_local oder extern deklariert wird, hat diese Variable eine automatische Speicherdauer. Beispiele sind x und y oben. Die Dauer solcher Variablen endet, wenn sie den Geltungsbereich verlassen. Das folgende Programm zeigt die automatische Speicherdauer als Referenz und einen Zeiger im globalen Bereich.

#enthalten
Verwenden von Namespace STD;
int x = 1;
int & m = x;
char y = 'a';
char* n = & y;
int main ()

Cout << m << *n << '\n';
Rückkehr 0;

Die Ausgabe ist 1A .

Die Dauer von M beginnt mit "int & m = x"; und endet am Ende des Programms. Die Dauer von n startet von "char* n = & y;" und endet am Ende des Programms.

Dynamische Speicherdauer

Kostenloser Laden

In einem modernen Computer kann mehr als ein Programm gleichzeitig ausgeführt werden. Jedes Programm hat einen eigenen Teil des Gedächtnisses. Der Rest des Speichers, der von keinem Programm verwendet wird, wird als kostenloser Laden bezeichnet. Der folgende Ausdruck wird verwendet, um einen Ort für eine Ganzzahl aus dem kostenlosen Laden zurückzugeben

Neu int

Dieser Standort (Speicher) für die zurückgegebene Ganzzahl muss noch durch Zuordnung zu einem Zeiger identifiziert werden. Der folgende Code zeigt, wie der Zeiger mit kostenlosem Laden verwendet wird:

int *ptrint = new int;
*ptrint = 12;
Cout<< *ptrInt <<'\n';

Die Ausgabe ist 12 .

Verwenden Sie den Löschenausdruck wie folgt, um ein Ende des Objekts zu beenden:

ptrint löschen;

Das Argument für den Ausdruck des Löschens ist ein Zeiger. Der folgende Code zeigt die Verwendung:

int *ptrint = new int;
*ptrint = 12;
ptrint löschen;

Ein Zeiger, der mit dem neuen Ausdruck erstellt und mit dem Löschausdruck gelöscht wird, hat eine dynamische Speicherdauer. Dieser Zeiger stirbt, wenn er aus dem Zielfernrohr geht oder gelöscht wird. Die Dauer des Objekts im vorherigen Code beginnt bei „*ptrint = 12“; und endet am Ende der deklarativen Region (Umfang). Es gibt mehr zu den neuen und löschenden Ausdrücken als hier diskutiert - siehe später.

Statische Speicherdauer

Statisches Objekt

Ein Objekt, das als statisch deklariert wurde, verhält sich wie das gewöhnliche Objekt, außer dass seine Speicherdauer von dem Zeitpunkt beginnt, an dem es bis zum Ende des Programms initialisiert wird. Es kann nicht außerhalb seines Geltungsbereichs gesehen werden, aber es kann indirekt von außerhalb seines Geltungsbereichs eingesetzt werden.

Betrachten Sie das folgende Programm, das von 1 bis 5 zählen soll (testen Sie das Programm nicht):

#enthalten
Verwenden von Namespace STD;
int fn ()

int stc = 1;
Cout << " << stc;
STC = STC + 1;
if (stc> 5)
Rückkehr 0;
fn ();

int main ()

fn ();
Rückkehr 0;

Der Ausgang ist 1 1 1 1 1 1 1 1… und nie wirklich endet. Die Funktionsdefinition ist eine wiederkehrende Funktion; Das heißt, es ruft sich immer wieder an, bis eine Bedingung erfüllt ist.

Die Lösung besteht darin, das STC -Objekt statisch zu machen. Sobald ein statisches Objekt initialisiert wurde, kann sein Wert nicht geändert werden, bis das Programm endet. Das folgende Programm (das Sie testen können), das dem oben genannten entspricht, aber jetzt mit STC statisch gemacht wird, zählt 1 bis 5:

#enthalten
Verwenden von Namespace STD;
int fn ()

statische int Stc = 1;
Cout << " << stc;
STC = STC + 1;
if (stc> 5)
Rückkehr 0;
fn ();

int main ()

fn ();
Rückkehr 0;

Der Ausgang ist: 1 2 3 4 5 .

Hinweis: Die Dauer eines statischen Objekts beginnt, wenn das Objekt initialisiert wurde, und endet am Ende des Programms. In der Zwischenzeit kann das Objekt indirekt aus einem anderen Bereich verwendet werden. Sobald ein statisches Objekt initialisiert wurde, kann sein Anfangswert nicht geändert werden, auch wenn seine Definition neu bewertet wird. Im obigen Code wird der STC nicht zurückgesetzt, wenn es das nächste Mal aufgerufen wird. Wenn es das nächste Mal aufgerufen wird, wird es durch "STC = STC + 1" erhöht;.

Statisches Datenmitglied

Eine Reihe verwandter Variablen und Funktionen können in eine verallgemeinerte Einheit bezeichnet werden, die als Klasse bezeichnet wird. Wenn die Variablen bestimmte Werte erhalten, wird die Klasse zu einem Objekt. Ein Objekt wird jedoch nicht erstellt, indem nur Werte der Variablen zugewiesen werden. Die Klasse wird instanziiert, um ein Objekt zu erhalten; und jedes erstellte Objekt hat seinen eigenen Namen anders als andere Objekte derselben Klasse. Das folgende Programm zeigt eine Klasse namens Thecla und ein Objekt namens OBJ; Es zeigt auch, wie das Objekt in der main () -Funktion instanziiert und verwendet wird:

#enthalten
Verwenden von Namespace STD;
Klasse Thecla

öffentlich:
int num;
void func (char cha, const char *str)
Cout << "There are " <<
num << " books worth " <<
Cha << str << " in the store." << '\n';

;
int main ()

Thecla obj;
obj.Num = 12;
obj.func ('$', "500");
Rückkehr 0;

Die Ausgabe ist:

Es gibt 12 Bücher im Wert von 500 US -Dollar im Laden.

Beachten Sie, dass das Objekt so instanziiert werden muss. Es ist dem Programmierer möglich, den Wert zuzuweisen, ohne ein Objekt zu instanziieren (erstellen). Um dies zu erreichen, muss die Variable Num als statisch deklariert werden. Dann wird es ohne den Objektnamen als "Thecla :: Num" zugegriffen, aber mit dem Klassennamen. Das folgende Programm zeigt dies:

#enthalten
Verwenden von Namespace STD;
Klasse Thecla

öffentlich:
statische const int num = 12;
void func (char cha, const char *str)
Cout << "There are " << num <<
"Bücher wert" << cha << str <<
" Im Laden." << '\n';

;
int main ()

Cout << TheCla::num << '\n';
Thecla obj;
obj.func ('$', "500");
Rückkehr 0;

Die Ausgabe ist:

12
Es gibt 12 Bücher im Wert von 500 US -Dollar im Laden.

Beachten Sie, dass der Umfangsauflösungsoperator :: verwendet werden musste. Auch nicht, dass die Variable, Num in der Klassenbeschreibung konstant und initialisiert werden musste (Definition).

Statische Mitgliedsfunktion

Beachten Sie, dass in der obigen vorherigen Programmauflistung ein Objekt so instanziiert werden musste, um die Func -Funktion in Main () zu verwenden. Es ist dem Programmierer möglich, die Funktion aufzurufen, ohne ein Objekt zu instanziieren (erstellen). Um dies zu erreichen, muss der Funktionsdefinition das Wort „statisch“ vorausgehen. Dann wird es ohne den Objektnamen als "Thecla :: func ()" zugegriffen, aber mit dem Klassennamen. Das folgende Programm zeigt dies für statische Datenmitglieder und statische Mitgliedsfunktion:

#enthalten
Verwenden von Namespace STD;
Klasse Thecla

öffentlich:
statische const int num = 12;
statischer void Func (Char Cha, const char *str)
Cout << "There are " << num <<
"Bücher wert" << cha << str <<
" Im Laden." << '\n';

;
int main ()

Thecla :: func ('$', "500");
Rückkehr 0;

Die Ausgabe ist:

Es gibt 12 Bücher im Wert von 500 US -Dollar im Laden.

Fadenspeicherdauer

Thread als Funktion in C ++, wurde vom G ++ - Compiler noch nicht implementiert. Anstatt dies zu erklären, wird das Zitat aus der C ++ - Spezifikation wie folgt angegeben:

  1. Alle mit dem Thread_local -Schlüsselwort deklarierten Variablen haben Threadspeicherdauer. Die Speicherung für diese Einheiten muss die Dauer des Fadens, in dem sie erstellt werden, dauern. Es gibt ein eindeutiges Objekt oder eine Referenz pro Thread, und die Verwendung des deklarierten Namens bezieht sich auf die Entität, die dem aktuellen Thread zugeordnet ist.
  2. Eine Variable mit der Speicherdauer der Gewinde muss vor ihrem ersten ODR-Gebrauch initialisiert und, falls konstruiert, am Gewindeausgang zerstört werden.”

Abschluss

Die Lebensdauer eines Objekts beginnt, wenn seine Initialisierung abgeschlossen ist, und endet, wenn sein Speicher veröffentlicht wird. Die dynamische Speicherdauer beginnt, wenn der von (neue Typ) erstellte Speicher initialisiert wird, und endet, wenn das Objekt aus dem Umfang ausgeht oder durch "Zeiger löschen" gelöscht wird. Die Dauer eines statischen Objekts beginnt, wenn das Objekt initialisiert wurde, und endet am Ende des Programms. Sobald ein statisches Objekt initialisiert wurde, kann sein Anfangswert nicht geändert werden, auch wenn seine Definition neu bewertet wird. Statische Datenmitglieder und statische Funktionsmitglieder werden außerhalb der Klassenbeschreibung mit "ClassName :: Name" zugegriffen.