Żywotność obiektu i czas przechowywania w C ++

Żywotność obiektu i czas przechowywania w C ++
Podczas tworzenia obiektu należy ustalić jego lokalizację w pamięci, zanim zostanie on zainicjowany. Inicjalizacja oznacza umieszczenie wartości w lokalizacji. Życie obiektu rozpoczyna się tuż po inicjalizacji. Gdy obiekt umiera, jego lokalizacja (pamięć), którą zajmowany obiekt jest zwolniony. Wydawanie pamięci oznacza, że ​​identyfikator lub wskaźnik zajmujący magazyn, nieprawidłowy. Żywotność obiektu kończy się, gdy jego przechowywanie jest zwolnione.

Potrzebny jest czas na utworzenie obiektu. Potrzebny jest czas na zabicie obiektu. Mówiąc o obiekcie, w grę wchodzą dwie rzeczy: lokalizacja, która jest magazynem i wartością. Znaczenie życia i czasu przechowywania jest podobne; ale czas trwania jest bardziej widoczny z punktu widzenia lokalizacji niż z punktu widzenia wartości. Czas przechowywania to czas, w którym lokalizacja jest powiązana z obiektem do czasu, w którym lokalizacja jest oddzielona od obiektu.

Reszta tego artykułu ilustruje życie obiektu i krótko wyjaśnia różne czasy przechowywania. Powinieneś mieć podstawową wiedzę w C ++, aby zrozumieć ten artykuł. Powinieneś również mieć wiedzę w zakresie C ++.

Treść artykułu

  • Ilustracja życia obiektu
  • Czas przechowywania
  • Automatyczny czas przechowywania
  • Dynamiczny czas przechowywania
  • Czas przechowywania statycznego
  • Czas przechowywania gwintu
  • Wniosek

Ilustracja życia obiektu

Rozważ następujący program:

#włączać
za pomocą przestrzeni nazw Std;
int main ()

if (1 == 1)

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

powrót 0;

Wyjście to 1a .

Życie obiektu dobiega końca, gdy zniknie z zakresu. Życie obiektu X zaczyna się od „x = 1;” i kończy się na końcu-local-scope. Życie obiektu y zaczyna się od „y =„ a ”;” i kończy się na końcu-local-scope. Przed śmiercią obu obiektów są zatrudnione w instrukcji Cout .

Czas przechowywania

Czas przechowywania jest określany przez jeden z następujących schematów: automatyczny czas przechowywania; Dynamiczny czas przechowywania; czas przechowywania statycznego; czas przechowywania gwintu. Kategorie czasu trwania przechowywania, dotyczą również referencji.

Automatyczny czas przechowywania

Jeśli zmienna nie jest wyraźnie zadeklarowana jako statyczna, Thread_Local lub Extern, to zmienna ma automatyczny czas przechowywania. Przykłady są x i y powyżej. Czas trwania takich zmiennych kończy się, gdy wychodzą z zakresu. Poniższy program ilustruje automatyczny czas przechowywania dla odniesienia i wskaźnika, w globalnym zakresie.

#włączać
za pomocą przestrzeni nazw Std;
int x = 1;
int & m = x;
char y = „a”;
char* n = & y;
int main ()

Cout << m << *n << '\n';
powrót 0;

Wyjście to 1a .

Czas trwania M zaczyna się od „int & m = x;” i kończy się na końcu programu. Czas trwania n zaczyna się od „char* n = & y;” i kończy się na końcu programu.

Dynamiczny czas przechowywania

Darmowy sklep

Na nowoczesnym komputerze może być jednocześnie więcej niż jeden program. Każdy program ma własną część pamięci. Reszta pamięci, która nie jest używana przez żaden program, jest znana jako bezpłatny sklep. Do zwrotu liczby całkowitej z bezpłatnego sklepu używane jest następujące wyrażenie

nowy int

Ta lokalizacja (pamięć) dla liczby całkowitej, zwróconej, nadal musi być zidentyfikowana przez przypisanie do wskaźnika. Poniższy kod ilustruje, jak korzystać z wskaźnika z bezpłatnym sklepem:

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

Wyjście to 12 .

Aby położyć kres życiu obiektu, użyj wyrażenia usuwania w następujący sposób:

usuń ptrint;

Argument o wyrażenie usunięcia jest wskaźnikiem. Poniższy kod ilustruje jego użycie:

int *ptrint = new int;
*ptrint = 12;
usuń ptrint;

Wskaźnik utworzony z nowym wyrażeniem i usunięto z wyrażeniem usuwania, ma dynamiczny czas przechowywania. Ten wskaźnik umiera, gdy wychodzi z zakresu lub jest usuwany. Czas trwania obiektu w poprzednim kodzie zaczyna się od „*ptrint = 12;” i kończy się na końcu regionu deklaratywnego (zakres). Nowe i usunięte wyrażenia to coś więcej niż omówiono tutaj - patrz później.

Czas przechowywania statycznego

Obiekt statyczny

Obiekt zadeklarowany statycznie zachowuje się jak zwykły obiekt, z wyjątkiem tego, że jego czas przechowywania zaczyna się od momentu inicjowania do końca programu. Nie można go zobaczyć poza jego zakresem, ale można go pośrednio stosować spoza jego zakresu.

Rozważ następujący program, który ma się liczyć od 1 do 5 (nie testuj programu):

#włączać
za pomocą przestrzeni nazw Std;
int fn ()

int stc = 1;
Cout << " << stc;
STC = STC + 1;
if (STC> 5)
powrót 0;
fn ();

int main ()

fn ();
powrót 0;

Wyjście to 1 1 1 1 1 1 1 1… i nigdy tak naprawdę nie kończy się. Definicja funkcji jest funkcją powtarzającą się; co oznacza, że ​​ciągle wzywa się, aż do spełnienia stanu.

Rozwiązaniem jest uczynienie obiektu STC statycznego. Po zainicjowaniu obiektu statycznego jego wartości nie można zmienić, dopóki program się nie zakończy. Poniższy program (który możesz przetestować), który jest taki sam jak powyżej, ale teraz ze statycznym STC, liczy się od 1 do 5:

#włączać
za pomocą przestrzeni nazw Std;
int fn ()

static int stc = 1;
Cout << " << stc;
STC = STC + 1;
if (STC> 5)
powrót 0;
fn ();

int main ()

fn ();
powrót 0;

Wyjście to: 1 2 3 4 5 .

Uwaga: Czas trwania obiektu statycznego zaczyna się, gdy obiekt został zainicjowany, a kończy na końcu programu. W międzyczasie obiekt można używać pośrednio, z innego zakresu. Po zainicjowaniu obiektu statycznego jego wartości początkowej nie można zmienić, nawet jeśli jego definicja zostanie ponownie oceniona. W powyższym kodzie STC nie jest resetowanie, następnym razem, gdy zostanie wywołany. Następnym razem, gdy zostanie wywołany, jest zwiększany przez „STC = STC + 1;”.

Statyczny element danych

Zestaw powiązanych zmiennych i funkcji można umieścić w uogólnionej jednostce o nazwie klasa. Jeśli zmienne otrzymują określone wartości, klasa staje się obiektem. Jednak obiekt nie jest tworzony przez przypisanie wartości do zmiennej. Klasa jest utworzona w celu uzyskania obiektu; a każdy utworzony obiekt ma swoją własną nazwę inną niż inne obiekty tej samej klasy. Poniższy program pokazuje klasę o nazwie Thecla i obiekt o nazwie OBJ; Pokazuje także, w jaki sposób obiekt jest tworzony i używany w funkcji Main ():

#włączać
za pomocą przestrzeni nazw Std;
klasa thecla

publiczny:
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”);
powrót 0;

Wyjście to:

W sklepie jest 12 książek o wartości 500 USD.

Zwróć uwagę, że aby przypisać wartość 12 do zmiennej NUM, obiekt musi zostać utworzony instancją, zanim przydzielenie będzie mogło nastąpić. Możliwe jest, że programista przypisuje wartość bez instancji (tworzenia) obiektu. Aby to osiągnąć, zmienna, NUM będzie musiała zostać zadeklarowana jako statyczna. Następnie dostęp do „thecla :: num” bez nazwy obiektu, ale z nazwą klasy. Poniższy program ilustruje to:

#włączać
za pomocą przestrzeni nazw Std;
klasa thecla

publiczny:
Static const int num = 12;
void Func (Char Cha, const char *str)
Cout << "There are " << num <<
„Książki warte” << cha << str <<
" w sklepie." << '\n';

;
int main ()

Cout << TheCla::num << '\n';
Thecla obj;
obj.FUNC („$”, „500”);
powrót 0;

Wyjście to:

12
W sklepie jest 12 książek o wartości 500 USD.

Należy zauważyć, że aby uzyskać dostęp do elementu danych, NUM in main (), operator rozdzielczości zakresu :: musiał być użyty. Również nie to, że zmienna NUM musiała być stała i zainicjowana w opisie klasy (definicja).

Statyczna funkcja członka

Zwróć uwagę, że w poprzednim listach programów powyżej, aby użyć funkcji FUNC w Main (), obiekt musiał zostać utworzony. Możliwe jest wywołanie funkcji bez instancji (tworzenia) obiektu. Aby to osiągnąć, definicja funkcji musi być poprzedzona słowem „statycznym”. Następnie dostęp do „thecla :: func ()” bez nazwy obiektu, ale z nazwą klasy. Poniższy program ilustruje to dla statycznego elementu danych i statycznego funkcji członka:

#włączać
za pomocą przestrzeni nazw Std;
klasa thecla

publiczny:
Static const int num = 12;
Static void Func (Char Cha, const char *str)
Cout << "There are " << num <<
„Książki warte” << cha << str <<
" w sklepie." << '\n';

;
int main ()

Thecla :: func („$”, „500”);
powrót 0;

Wyjście to:

W sklepie jest 12 książek o wartości 500 USD.

Czas przechowywania gwintu

Wątek jako funkcja w C ++ nie została jeszcze zaimplementowana przez kompilator G ++. Zamiast tego wyjaśnianie, cytat ze specyfikacji C ++ jest podany w następujący sposób:

  1. Wszystkie zmienne zadeklarowane słowem kluczowym Thread_Local mają czas przechowywania wątku. Przechowywanie dla tych podmiotów będzie trwać czas trwania wątku, w którym są tworzone. Istnieje wyraźny obiekt lub odniesienie na wątek, a użycie zadeklarowanej nazwy odnosi się do jednostki powiązanej z bieżącym wątkiem.
  2. Zmienna z czasem przechowywania gwintu powinna zostać zainicjowana przed pierwszym użyciem ODR i, jeśli skonstruowana, zostanie zniszczona po wyjściu z wątku."

Wniosek

Żywotność obiektu zaczyna się po zakończeniu jego inicjalizacji, a kończy się po zwolnieniu jego przechowywania. Dynamiczny czas trwania pamięci rozpoczyna się, gdy pamięć utworzona przez (nowy typ) jest inicjowany, a kończy się, gdy obiekt wychodzi z zakresu lub zostanie usunięty przez „Wskaźnik Usuń”. Czas trwania obiektu statycznego zaczyna się, gdy obiekt został zainicjowany i kończy się na końcu programu. Po zainicjowaniu obiektu statycznego jego wartości początkowej nie można zmienić, nawet jeśli jego definicja zostanie ponownie oceniona. Dostęp do statycznych członków danych i statycznych funkcji są dostępne poza opisem klasy z „ClassName :: Nazwa”.