Gültigkeitsbereich (C++)
Wenn Sie ein Programmelement wie eine Klasse, Funktion oder Variable deklarieren, kann der Name nur "gesehen" und in bestimmten Teilen des Programms verwendet werden. Der Kontext, in dem ein Name sichtbar ist, wird als Bereich bezeichnet. Wenn Sie beispielsweise eine Variable x
innerhalb einer Funktion deklarieren, x
ist nur innerhalb dieses Funktionstexts sichtbar. Er verfügt über einen lokalen Bereich. Möglicherweise haben Sie andere Variablen mit demselben Namen in Ihrem Programm; solange sie sich in unterschiedlichen Bereichen befinden, verstoßen sie nicht gegen die One Definition Rule, und es wird kein Fehler ausgelöst.
Bei automatischen nicht statischen Variablen bestimmt der Bereich auch, wann sie im Programmspeicher erstellt und zerstört werden.
Es gibt sechs Arten von Umfang:
Globaler Bereich Ein globaler Name ist ein Name, der außerhalb einer Klasse, Funktion oder eines Namespace deklariert wird. In C++ existieren diese Namen jedoch auch mit einem impliziten globalen Namespace. Der Bereich der globalen Namen reicht vom Deklarationspunkt bis zum Ende der Datei, in der sie deklariert werden. Bei globalen Namen unterliegt die Sichtbarkeit auch den Regeln der Verknüpfung , die bestimmen, ob der Name in anderen Dateien im Programm sichtbar ist.
Namespacebereich A name that is declared within a namespace, outside of any class or enum definition or function block, is visible from its point of declaration to the end of namespace. Ein Namespace kann in mehreren Blöcken in verschiedenen Dateien definiert werden.
Lokaler Bereich A-Name, der in einer Funktion oder Lambda deklariert wurde, einschließlich der Parameternamen, weisen einen lokalen Bereich auf. Sie werden häufig als "Locals" bezeichnet. Sie sind nur von ihrem Deklarationspunkt bis zum Ende der Funktion oder des Lambda-Texts sichtbar. Der lokale Bereich ist eine Art Blockbereich, der weiter unten in diesem Artikel erläutert wird.
Klassenbereichsnamen von Klassenmitgliedern weisen einen Klassenbereich auf, der unabhängig vom Deklarationspunkt in der gesamten Klassendefinition erweitert wird. Die Barrierefreiheit von Klassenmitglieds wird weiter durch die
public
Schlüsselwörter ,private
undprotected
die Barrierefreiheit von Klassenmememnwörtern gesteuert. Auf öffentliche oder geschützte Member kann nur über die Memberauswahloperatoren (. oder> -) oder Zeiger-zu-Member-Operatoren (oder -*>) zugegriffen werden.*Anweisungsbereichsnamen , die in einem
for
,if
,while
, oderswitch
einer Anweisung deklariert sind, sind bis zum Ende des Anweisungsblocks sichtbar.Funktionsbereich A hat Funktionsbereich, was bedeutet, dass sie im gesamten Funktionstext sichtbar ist, auch vor dem Deklarationspunkt. Der Funktionsbereich ermöglicht das Schreiben von Anweisungen wie
goto cleanup
vor der Deklaration dercleanup
Bezeichnung.
Ausblenden von Namen
Sie können einen Namen verbergen, indem Sie ihn in einem eingeschlossenen Block deklarieren. In der folgenden Abbildung wird i
innerhalb des inneren Blocks neu deklariert. Dadurch wird die Variable ausgeblendet, die i
im äußeren Blockbereich zugeordnet ist.
Blockbereich und Name ausblenden
Die in der Abbildung dargestellte Ausgabe des Programms lautet wie folgt:
i = 0
i = 7
j = 9
i = 0
Hinweis
Es wird angenommen, dass das szWhat
-Argument im Funktionsbereich liegt. Daher wird es so behandelt, als wäre es im äußersten Block der Funktion deklariert worden.
Ausblenden von Klassennamen
Sie können Klassennamen ausblenden, indem Sie eine Funktion, ein Objekt, eine Variable oder einen Enumerator im gleichen Bereich deklarieren. Auf den Klassennamen kann jedoch weiterhin zugegriffen werden, wenn dem Schlüsselwort class
das Präfix vorangestellt wird.
// 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
Hinweis
Jeder Ort, für den der Klassenname (Account
) aufgerufen wird, muss die Schlüsselwortklasse verwendet werden, um sie von der globalen Variablen "Account" zu unterscheiden. Diese Regel gilt nicht, wenn der Klassenname auf der linken Seite des Bereichsauflösungsoperators (::) auftritt. Namen auf der linken Seite des Bereichsauflösungsoperators gelten immer als Klassennamen.
Im folgenden Beispiel wird das Deklarieren eines Zeigers auf ein Objekt vom Typ Account
mithilfe des class
Schlüsselworts veranschaulicht:
class Account *Checking = new class Account( Account );
Der Account
Initialisierer (in Klammern) in der vorherigen Anweisung hat einen globalen Bereich; er ist vom Typ double
.
Hinweis
Die in diesem Beispiel dargestellte Wiederverwendung von Bezeichnernamen gilt als schlechter Programmierstil.
Informationen zur Deklaration und Initialisierung von Klassenobjekten finden Sie unter "Klassen", "Strukturen" und "Unions". Informationen zur Verwendung der new
Operatoren für delete
den freien Store finden Sie unter neuen und Löschoperatoren.
Ausblenden von Namen mit globalem Bereich
Sie können Namen mit globalem Bereich ausblenden, indem Sie denselben Namen explizit im Blockbereich deklarieren. Auf Globale Bereichsnamen kann jedoch über den Bereichsauflösungsoperator (::
) zugegriffen werden.
#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