7.12 — Zakres, czas trwania i podsumowanie powiązań

Pojęcia zakresu, czasu trwania i powiązań powodują wiele zamieszania, dlatego poświęcimy dodatkową lekcję, aby wszystko podsumować. Niektórych z tych rzeczy jeszcze nie omówiliśmy i są one tutaj tylko dla uzupełnienia/odniesienia później.

Podsumowanie zakresu

Identyfikator zakres określa, gdzie w kodzie źródłowym można uzyskać dostęp do identyfikatora.

  • Zmienne o zakresie blokowym (lokalnym) można uzyskać dostęp tylko od momentu deklaracji do końca bloku, w którym są zadeklarowane (w tym zagnieżdżone bloki). Obejmuje to:
    • Zmienne lokalne
    • Parametry funkcji
    • Definicje typów zdefiniowanych w programie (takie jak wyliczenia i klasy) zadeklarowane wewnątrz bloku
  • Dostęp do zmiennych i funkcji za pomocą zasięgiem globalnym można uzyskać od momentu deklaracji aż do końca pliku. Obejmuje to:
    • Zmienne globalne
    • Funkcje
    • Definicje typów zdefiniowanych przez program (takie jak wyliczenia i klasy) zadeklarowane w przestrzeni nazw lub w zasięgu globalnym

Podsumowanie czasu trwania

Przechowywanie zmiennej czasu trwania określa, kiedy jest on tworzony i niszczony.

  • Zmienne o automatycznym Duration są tworzone w momencie definicji i niszczone po wyjściu z bloku, którego są częścią. Obejmuje to:
    • Zmienne lokalne
    • Parametry funkcji
  • Zmienne o czas statyczny są tworzone podczas uruchamiania programu i niszczone po zakończeniu programu. Obejmuje to:
    • Zmienne globalne
    • Statyczne zmienne lokalne
  • Zmienne o dynamicznym czasie trwania są tworzone i niszczone na żądanie programisty. Obejmuje to:
    • Dynamicznie przydzielane zmienne

Podsumowanie powiązań

Identyfikator połączenie określa, czy deklaracja tego samego identyfikatora w innym zakresie odnosi się do tej samej jednostki (obiektu, funkcji, odniesienia itp.) czy nie.

Zmienne lokalne nie mają powiązania. Każda deklaracja identyfikatora bez powiązania odnosi się do unikalnego obiektu lub funkcji.

  • Identyfikator z brak powiązania oznacza, że ​​kolejna deklaracja tego samego identyfikatora odnosi się do unikalnej jednostki. Jednostki, których identyfikatory nie mają powiązania, obejmują:
    • Zmienne lokalne
    • Zdefiniowane przez program identyfikatory typów (takie jak wyliczenia i klasy) zadeklarowane wewnątrz bloku
  • Identyfikator z powiązanie wewnętrzne oznaczają deklarację tego samego identyfikatora w tej samej jednostce translacji, która odnosi się do tego samego obiektu lub funkcji. Do jednostek, których identyfikatory mają wewnętrzne powiązanie, zaliczają się:
    • Statyczne zmienne globalne (zainicjowane lub niezainicjowane)
    • Funkcje statyczne
    • Stałe zmienne globalne
    • Nienazwane przestrzenie nazw i wszystko, co jest w nich zdefiniowane
  • Identyfikator z powiązanie zewnętrzne oznacza deklarację tego samego identyfikatora w całym programie, odnoszącą się do tego samego obiektu lub funkcji. Jednostki, których identyfikatory mają zewnętrzne powiązanie obejmują:
    • Funkcje niestatyczne
    • Niestałe zmienne globalne (zainicjowane lub niezainicjowane)
    • Zewnętrzne zmienne globalne const
    • Wbudowane zmienne globalne const
    • Przestrzenie nazw

Identyfikatory z zewnętrznym powiązaniem zazwyczaj powodują błąd linkera zduplikowanej definicji, jeśli definicje są kompilowane do więcej niż jednego pliku .cpp (ze względu na naruszenie zasady jednej definicji). Istnieje kilka wyjątków od tej reguły (dla typów, szablonów oraz funkcji i zmiennych wbudowanych) — omówimy je szerzej w przyszłych lekcjach, gdy będziemy omawiać te tematy.

Pamiętaj również, że funkcje mają domyślnie zewnętrzne połączenie. Można je uczynić wewnętrznymi za pomocą słowa kluczowego static.

Zakres zmiennej, czas trwania i podsumowanie powiązań

Ponieważ zmienne mają zakres, czas trwania i powiązanie, podsumujmy na wykresie:

TypPrzykładZakresCzas trwaniaPowiązanieUwagi
Lokalne zmiennaint x;BlokujAutomatycznyBrak
Statyczna zmienna lokalnastatic int s_x;BlokujStatycznyBrak
Dynamiczna zmienna lokalnaint* x { nowy int{} };BlokujDynamicznyBrak
Parametr funkcjivoid foo(int x)BlokujAutomatycznyBrak
Wewnętrzna niestała zmienna globalnastatic int g_x;GlobalnyStatycznyWewnętrznyZainicjowany lub niezainicjowany
Zewnętrzna niestała globalna zmiennaint g_x;GlobalnyStatycznyZewnętrznyZainicjowany lub niezainicjowany
Wbudowana zmienna globalna niestała (C++17)wbudowana int g_x;GlobalnyStatycznyZewnętrznyZainicjowany lub niezainicjowany
Wewnętrzna stała zmienna globalnaconstexpr int g_x { 1 };GlobalnyStatycznyWewnętrznyNależy zainicjować
Zewnętrzna stała zmienna globalnaextern const int g_x { 1 };GlobalnyStatycznyZewnętrznyNależy zainicjować
Wbudowana stała zmienna globalna (C++17)inline constexpr int g_x { 1 };GlobalnyStatycznyZewnętrznyNależy zainicjować

Przekaż podsumowanie deklaracji

Możesz użyć deklaracji forward, aby uzyskać dostęp do funkcji lub zmiennej w innym pliku. Zakres zadeklarowanej zmiennej jest taki sam jak zwykle (zasięg globalny dla globali, zakres blokowy dla lokalnych).

TypPrzykładUwagi
Deklaracja forward funkcjivoid foo(int x);Tylko prototyp, bez treści funkcji
Deklaracja zmiennej innej niż stałaextern int g_x;Musi być niezainicjowana
Deklaracja forward zmiennej constextern const int g_x;Musi być niezainicjowana
Deklaracja naprzód zmiennej constexprextern constexpr int g_x;Niedozwolone, constexpr nie można zadeklarować w przód

Zmienna constexpr (która domyślnie jest const) może zostać zadeklarowana w przód przy użyciu deklaracji forward zmiennej const. W przypadku dostępu poprzez deklarację forward zmienna będzie uważana za const (a nie constexpr).

Co to do cholery jest specyfikator klasy pamięci?

Kiedy są używane jako część deklaracji identyfikatora, static i extern słowa kluczowe nazywane są specyfikatorami klas pamięci. W tym kontekście ustawiają czas przechowywania i powiązanie identyfikatora.

C++ obsługuje 4 aktywne specyfikatory klasy pamięci:

SpecifierZnaczenieUwaga
zewnętrznystatyczny (lub wątek_lokalny) czas przechowywania i zewnętrzne połączenie
statycznystatyczny (lub wątek_lokalny) czas przechowywania i wewnętrzne powiązanie
wątek_lokalnyprzechowywanie wątków czas trwania
zmiennyobiekt można modyfikować, nawet jeśli zawierający klasę jest const
automatycznyautomatyczny czas przechowywaniaPrzestarzałe w C++11
rejestrautomatyczne zapisywanie czasu trwania i wskazówka dla kompilatora, aby umieścić go w rejestrzePrzestarzałe w C++17

Termin specyfikatora klasy pamięci jest zwykle używany tylko w dokumentacji formalnej.

guest
Twój adres e-mail nie zostanie wyświetlony
Znalazłeś błąd? Zostaw komentarz powyżej!
Komentarze związane z poprawkami zostaną usunięte po przetworzeniu, aby pomóc zmniejszyć bałagan. Dziękujemy za pomoc w ulepszaniu witryny dla wszystkich!
Awatary z https://gravatar.com/ są połączone z podanym adresem e-mail.
Powiadamiaj mnie o odpowiedziach:  
198 Komentarze
Najnowsze
Najstarsze Najczęściej głosowane
Wbudowane opinie
Wyświetl wszystkie komentarze