Zakres (C++)
W przypadku deklarowania elementu programu, takiego jak klasa, funkcja lub zmienna, jego nazwa może być widoczna tylko w niektórych częściach programu. Kontekst, w którym jest widoczna nazwa, jest nazywany jego zakresem. Jeśli na przykład zadeklarujesz zmienną x
w funkcji, x
będzie widoczna tylko w tej treści funkcji. Ma on zakres lokalny. Możesz mieć inne zmienne o tej samej nazwie w programie; o ile znajdują się one w różnych zakresach, nie naruszają reguły jednej definicji i nie są zgłaszane żadne błędy.
W przypadku automatycznych zmiennych niestacjonanych zakres określa również, kiedy są tworzone i niszczone w pamięci programu.
Istnieje sześć rodzajów zakresu:
Zakres globalny Nazwa globalna to nazwa zadeklarowana poza dowolną klasą, funkcją lub przestrzenią nazw. Jednak w języku C++ nawet te nazwy istnieją z niejawną globalną przestrzenią nazw. Zakres nazw globalnych rozciąga się od punktu deklaracji na koniec pliku, w którym są deklarowane. W przypadku nazw globalnych widoczność podlega również regułom łączenia , które określają, czy nazwa jest widoczna w innych plikach w programie.
Zakres przestrzeni nazw Nazwa zadeklarowana w przestrzeni nazw poza dowolną definicją klasy lub definicją wyliczenia lub blokiem funkcji jest widoczna z punktu deklaracji na końcu przestrzeni nazw. Przestrzeń nazw może być zdefiniowana w wielu blokach w różnych plikach.
Zakres lokalny Nazwa zadeklarowana w funkcji lub lambda, w tym nazwy parametrów, mają zakres lokalny. Są one często określane jako "lokalne". Są one widoczne tylko z punktu deklaracji na końcu funkcji lub treści lambda. Zakres lokalny jest rodzajem zakresu blokowego, który został omówiony w dalszej części tego artykułu.
Nazwy zakresów klas składowych klasy mają zakres klas, który rozciąga się w całej definicji klasy niezależnie od punktu deklaracji. Ułatwienia dostępu składowych klasy są dodatkowo kontrolowane przez
public
słowa kluczowe ,private
iprotected
. Dostęp do publicznych lub chronionych elementów członkowskich można uzyskać tylko za pomocą operatorów wyboru składowych (. lub ->) lub operatorów wskaźnika do składowych (.* lub -).>*Nazwy zakresu instrukcji zadeklarowane w instrukcji
for
,if
,while
lubswitch
są widoczne do końca bloku instrukcji.Zakres funkcji Etykietafunkcji ma zakres funkcji, co oznacza, że jest widoczny w całej treści funkcji jeszcze przed jego punktem deklaracji. Zakres funkcji umożliwia pisanie instrukcji, takich jak
goto cleanup
przed zadeklarowaną etykietącleanup
.
Ukrywanie nazw
Nazwę można ukryć, deklarując ją w zamkniętym bloku. Na poniższej ilustracji i
element jest ponownie zadeklarowany w bloku wewnętrznym, ukrywając w ten sposób zmienną skojarzona z i
zakresem bloku zewnętrznego.
Blokuj ukrywanie zakresu i nazwy
Dane wyjściowe programu pokazane na rysunku to:
i = 0
i = 7
j = 9
i = 0
Uwaga
Argument szWhat
jest uważany za w zakresie funkcji. W związku z tym jest traktowana tak, jakby została zadeklarowana w najbardziej zewnętrznym bloku funkcji.
Ukrywanie nazw klas
Nazwy klas można ukryć, deklarując funkcję, obiekt lub zmienną albo moduł wyliczający w tym samym zakresie. Jednak nazwa klasy nadal może być dostępna po prefiksie słowa kluczowego class
.
// hiding_class_names.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
// Declare class Account at global scope.
class Account
{
public:
Account( double InitialBalance )
{ balance = InitialBalance; }
double GetBalance()
{ return balance; }
private:
double balance;
};
double Account = 15.37; // Hides class name Account
int main()
{
class Account Checking( Account ); // Qualifies Account as
// class name
cout << "Opening account with a balance of: "
<< Checking.GetBalance() << "\n";
}
//Output: Opening account with a balance of: 15.37
Uwaga
Każde miejsce, dla którego jest wywoływana nazwa klasy (Account
), należy użyć klasy słowa kluczowego, aby odróżnić ją od konta zmiennej o zakresie globalnym. Ta reguła nie ma zastosowania, gdy nazwa klasy występuje po lewej stronie operatora rozpoznawania zakresu (::). Nazwy po lewej stronie operatora rozpoznawania zakresu są zawsze uznawane za nazwy klas.
W poniższym przykładzie pokazano, jak zadeklarować wskaźnik do obiektu typu Account
przy użyciu słowa kluczowego class
:
class Account *Checking = new class Account( Account );
Inicjator Account
(w nawiasach) w poprzedniej instrukcji ma zakres globalny; jest double
typu .
Uwaga
Ponowne użycie nazw identyfikatorów, jak pokazano w tym przykładzie, jest uznawane za słaby styl programowania.
Aby uzyskać informacje o deklarowaniu i inicjowaniu obiektów klasy, zobacz Klasy, struktury i unii. Aby uzyskać informacje o korzystaniu z new
operatorów magazynu i delete
, zobacz operatory nowych i usuwania.
Ukrywanie nazw przy użyciu zakresu globalnego
Nazwy z zakresem globalnym można ukryć, jawnie deklarując tę samą nazwę w zakresie bloku. Można jednak uzyskać dostęp do nazw zakresów globalnych przy użyciu operatora rozpoznawania zakresu (::
).
#include <iostream>
int i = 7; // i has global scope, outside all blocks
using namespace std;
int main( int argc, char *argv[] ) {
int i = 5; // i has block scope, hides i at global scope
cout << "Block-scoped i has the value: " << i << "\n";
cout << "Global-scoped i has the value: " << ::i << "\n";
}
Block-scoped i has the value: 5
Global-scoped i has the value: 7
Zobacz też
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla