Geltungsbereich in C++

Scope C



Eine Entität in C++ hat einen Namen, der deklariert und/oder definiert werden kann. Eine Deklaration ist eine Definition, aber eine Definition ist nicht unbedingt eine Deklaration. Eine Definition weist Speicher für die benannte Entität zu, aber eine Deklaration kann Speicher für die benannte Entität zuweisen oder nicht. Eine deklarative Region ist der größte Teil eines Programms, in dem der Name einer Entität (Variable) gültig ist. Diese Region wird als Scope oder potentieller Scope bezeichnet. In diesem Artikel wird die Bereichsbestimmung in C++ erläutert. Darüber hinaus sind Grundkenntnisse in C++ erforderlich, um diesen Artikel zu verstehen.

Artikelinhalt

Deklarativer Bereich und Geltungsbereich

Ein deklarativer Bereich ist der größte Teil eines Programmtextes, in dem der Name einer Entität gültig ist. Es ist die Region, in der der unqualifizierte Name verwendet (gesehen) werden kann, um auf dieselbe Entität zu verweisen. Betrachten Sie das folgende kurze Programm:







#enthalten
mit Namensraumstd;

Leerefn()
{
intwo= 3;
wenn (1==1)
{
Kosten<<wo<<' ';
}
}

inthauptsächlich()
{
fn();
Rückkehr 0;
}

Die Funktion fn() hat zwei Blöcke: einen inneren Block für die if-Bedingung und einen äußeren Block für den Funktionsrumpf. Der Bezeichner var wird eingeführt und im äußeren Block angezeigt. Es ist auch im inneren Block mit der cout-Anweisung zu sehen. Der äußere und der innere Block sind beide der Geltungsbereich für den Namen var.



Der Name var kann jedoch weiterhin verwendet werden, um eine andere Entität wie beispielsweise ein Float im inneren Block zu deklarieren. Der folgende Code veranschaulicht dies:



#enthalten
mit Namensraumstd;

Leerefn()
{
intwo= 3;
wenn (1==1)
{
schwebenwo= 7,5;
Kosten<<wo<<' ';
}
}

inthauptsächlich()
{
fn();
Rückkehr 0;
}

Die Ausgabe ist 7,5. In diesem Fall kann der Name var im inneren Block nicht mehr verwendet werden, um auf die ganze Zahl mit dem Wert 3 zu verweisen, die im äußeren Block eingeführt (deklariert) wurde. Solche inneren Blöcke werden als potenzieller Geltungsbereich für im äußeren Block deklarierte Entitäten bezeichnet.





Hinweis: Eine Entität des gleichen Typs, wie die des äußeren Blocks, kann weiterhin im inneren Block deklariert werden. In diesem Fall gilt jedoch im inneren Block die neue Deklaration und ihre Bedeutung, während die alte Deklaration und ihre Bedeutung außerhalb des inneren Blocks im äußeren Block gültig bleibt.

Eine gleichnamige Deklaration in einem inneren Block überschreibt normalerweise die gleichnamige Deklaration außerhalb dieses inneren Blocks. Innere Blöcke können andere innere Blöcke verschachteln.



Globaler Geltungsbereich

Wenn ein Programmierer gerade mit der Eingabe einer Datei beginnt, ist dies der globale Geltungsbereich. Das folgende kurze Programm veranschaulicht dies:

#enthalten
mit Namensraumstd;

schwebenwo= 9,4;

inthauptsächlich()
{
Kosten <<wo<<' ';
Kosten <<::wo<<' ';

Rückkehr 0;
}

Die Ausgabe ist:
9,4
9,4

In diesem Fall beginnt der deklarative Bereich bzw. Geltungsbereich für var ab dem Deklarationspunkt für var und setzt sich nach unten bis zum Ende der Datei (Übersetzungseinheit) fort.

Der Block der Funktion main() ist ein anderer Geltungsbereich; es ist ein verschachtelter Bereich für den globalen Bereich. Um auf eine Entität des globalen Geltungsbereichs von einem anderen Geltungsbereich aus zuzugreifen, wird der Bezeichner direkt verwendet oder dem Geltungsbereichsauflösungsoperator vorangestellt, :: .

Hinweis: Die Entität main() wird auch im globalen Gültigkeitsbereich deklariert.

Blockbereich

Die if-, while-, do-, for- oder switch-Anweisungen können jeweils einen Block definieren. Eine solche Aussage ist eine zusammengesetzte Aussage. Der Name einer in einem Block deklarierten Variablen hat den Gültigkeitsbereich eines Blocks. Sein Gültigkeitsbereich beginnt am Deklarationspunkt und endet am Ende seines Blocks. Das folgende kurze Programm veranschaulicht dies für die Variable ident:

#enthalten
mit Namensraumstd;

inthauptsächlich()
{
wenn (1==1)
{
/*einige Aussagen*/
intident= 5;
Kosten<<ident<<' ';
/*einige Aussagen*/
}
Rückkehr 0;
}

Eine Variable wie ident, die im Blockbereich deklariert wird, ist eine lokale Variable.

Eine außerhalb des Blockbereichs und darüber deklarierte Variable ist im Header des Blocks (z. B. Bedingung für if-Block) und auch innerhalb des Blocks zu sehen. Das folgende kurze Programm veranschaulicht dies für die Variable identif:

#enthalten
mit Namensraumstd;

inthauptsächlich()
{
intidentifizieren= 8;

wenn (identifizieren== 8)
{
Kosten<<identifizieren<<' ';
}
Rückkehr 0;
}

Die Ausgabe ist 8. Hier gibt es zwei Blockbereiche: den Block für die main()-Funktion und die verschachtelte if-compound-Anweisung. Der verschachtelte Block ist der potenzielle Geltungsbereich des main()-Funktionsblocks.

Eine in einen Blockbereich eingefügte Deklaration ist außerhalb des Blocks nicht sichtbar. Das folgende kurze Programm, das nicht kompiliert, veranschaulicht dies mit der Variablen variab:

#enthalten
mit Namensraumstd;

inthauptsächlich()
{
wenn (1 == 1)
{
intvariab= fünfzehn;
}
Kosten<<variab<<' '; //Fehler: Zugriff außerhalb des Gültigkeitsbereichs.

Rückkehr 0;
}

Der Compiler erzeugt eine Fehlermeldung für variab.

Eine eingeführte Entität, die im Header einer zusammengesetzten Funktion deklariert ist, kann außerhalb (unterhalb) der zusammengesetzten Anweisung nicht gesehen werden. Der folgende for-Schleifencode wird nicht kompiliert, was zu einer Fehlermeldung führt:

#enthalten
mit Namensraumstd;

inthauptsächlich()
{
zum (intich=0;ich<4; ++ich)
{
Kosten<<ich<<'';
}
Kosten<<ich<<'';

Rückkehr 0;
}

Die Iterationsvariable i wird innerhalb des for-Schleifenblocks gesehen, aber nicht außerhalb des for-Schleifenblocks.

Funktionsumfang

Im Funktionsblock ist ein Funktionsparameter zu sehen. Eine in einem Funktionsblock deklarierte Entität wird vom Deklarationspunkt bis zum Ende des Funktionsblocks betrachtet. Das folgende kurze Programm veranschaulicht dies:

#enthalten
#enthalten
mit Namensraumstd;

Zeichenfolge fn(Saitenstr)
{
verkohlenstr[] = 'Bananen';
/*andere Aussagen*/
Zeichenfolge totalStr=P+str;
RückkehrtotalStr;
}

inthauptsächlich()
{
Zeichenfolge totStr=fn('Essen ');
Kosten<<totStr<<' ';

Rückkehr 0;
}

Die Ausgabe ist:
Bananen essen

Hinweis: Eine außerhalb der Funktion (darüber) deklarierte Entität ist in der Funktionsparameterliste und auch im Funktionsblock zu sehen.

Etikett

Der Geltungsbereich eines Labels ist die Funktion, in der es erscheint. Der folgende Code veranschaulicht dies:

#enthalten
mit Namensraumstd;

Leerefn()
{
gehe zulabl;
/*andere Aussagen*/
labl: intnicht= 2;
Kosten<<nicht<<' ';
}

inthauptsächlich()
{
fn();

Rückkehr 0;
}

Die Ausgabe ist 2.

Aufzählungsbereich

Aufzählung ohne Gültigkeitsbereich
Betrachten Sie den folgenden if-Block:

wenn (1==1)
{
aufzählen {a, b, c=B+2};
Kosten<<zu<<''<<B<<''<<C<<' ';
}

Die Ausgabe ist 0 1 3.

Die erste Zeile im Block ist eine Aufzählung, a, b und c sind ihre Aufzählungen. Der Gültigkeitsbereich eines Enumerators beginnt vom Deklarationspunkt bis zum Ende des umschließenden Blocks der Enumeration.

Die folgende Anweisung wird nicht kompiliert, da der Deklarationspunkt von c nach dem von a liegt:

aufzählen {zu=C+2, b, c};

Das folgende Codesegment wird nicht kompiliert, da auf die Enumeratoren nach dem einschließenden Block der Enumeration zugegriffen wird:

wenn (1==1)
{
aufzählen {a, b, c=B+2};
}
Kosten<<zu<<''<<B<<''<<C<<' '; //Fehler: außerhalb des Gültigkeitsbereichs

Die obige Aufzählung wird als Aufzählung ohne Bereichsgrenzen beschrieben, und ihre Aufzählungen werden als Aufzählungen ohne Bereichsgrenzen beschrieben. Dies liegt daran, dass es nur mit dem reservierten Wort enum beginnt. Aufzählungen, die mit Aufzählungsklasse oder Aufzählungsstruktur beginnen, werden als bereichsbezogene Aufzählungen bezeichnet. Ihre Enumeratoren werden als bereichsbezogene Enumeratoren bezeichnet.

Bereichsbezogene Aufzählung
Die folgende Aussage ist in Ordnung:

aufzählen Klassemännlich{a, b, c=B+2};

Dies ist ein Beispiel für eine bereichsbezogene Enumeration. Der Name der Klasse ist nam. Hier beginnt der Gültigkeitsbereich des Enumerators vom Deklarationspunkt bis zum Ende der Aufzählungsdefinition und nicht bis zum Ende des umschließenden Blocks für die Aufzählung. Der folgende Code wird nicht kompiliert:

wenn (1==1)
{
aufzählen Klassemännlich{a, b, c=B+2};
Kosten<<zu<<''<<B<<''<<C<<' '; //Fehler: außerhalb des Gültigkeitsbereichs für Enum-Klasse oder Enum-Struktur
}

Klassenumfang

Beim normalen Scoping beginnt der deklarative Bereich an einem Punkt, wird dann fortgesetzt und endet an einem anderen Punkt. Der Geltungsbereich existiert in einem zusammenhängenden Bereich. Mit der Klasse kann der Geltungsbereich einer Entität in verschiedenen Regionen liegen, die nicht miteinander verbunden sind. Die Regeln für verschachtelte Blöcke gelten weiterhin. Das folgende Programm veranschaulicht dies:

#enthalten
mit Namensraumstd;

//Basisklasse
KlasseCla
{
Privatgelände:
intmemP= 5;
geschützt:
intmemPro= 9;
öffentlich:
Leerefn()
{
Kosten<<memP<<' ';
}
};

//Abgeleitete Klasse
KlasseDerCla: öffentlichCla
{
öffentlich:
intderMem=memPro;
};
inthauptsächlich()
{
Cla obj;
obj.fn();
DerCla derObj;
Kosten<<derObj.derMem<<' ';

Rückkehr 0;
}

Die Ausgabe ist:
5
9

In der Klasse Cla wird die Variable memP an der Deklarationsstelle gesehen. Danach wird der kurze Teil von protected übersprungen und dann wieder im Klassenmember-Funktionsblock angezeigt. Die abgeleitete Klasse wird übersprungen und dann wieder im main()-Funktionsbereich (Block) angezeigt.

In der Klasse Cla wird die Variable memPro an der Deklarationsstelle gesehen. Der Teil der öffentlichen Funktion fn() wird übersprungen und dann im abgeleiteten Klassenbeschreibungsblock angezeigt. Es wird wieder unten in der main()-Funktion angezeigt.

Scope Resolution Operator
Der Bereichsauflösungsoperator in C++ ist :: . Es wird verwendet, um auf ein statisches Mitglied der Klasse zuzugreifen. Das folgende Programm veranschaulicht dies:

#enthalten
mit Namensraumstd;

KlasseCla
{
öffentlich:
statisch int constmeme= 5;
öffentlich:
statisch Leerefn()
{
Kosten<<meme<<' ';
}
};
inthauptsächlich()
{
Kosten<<Cla::meme<<' ';
Cla::fn();

Rückkehr 0;
}

Die Ausgabe ist:
5
5

Die statischen Member werden im main()-Funktionsblock angezeigt, auf den über den Bereichsauflösungsoperator zugegriffen wird.

Vorlagenparameterbereich

Der normale Gültigkeitsbereich eines Vorlagenparameternamens beginnt vom Deklarationspunkt bis zum Ende seines Blocks, wie im folgenden Code:

Vorlage<ModellnameT,ModellnameU> strukturierenAlter
{
T John= elf;
Du Peter= 12,3;
T Maria= 13;
U Freude= 14,6;
};

U und T sind innerhalb des Blocks zu sehen.

Bei einem Vorlagenfunktionsprototyp beginnt der Gültigkeitsbereich vom Deklarationspunkt bis zum Ende der Funktionsparameterliste, wie in der folgenden Anweisung:

Vorlage<ModellnameT,ModellnameU> LeereFunktion(Du nein, du cha,const verkohlen *P);

Bei der Klassenbeschreibung (Definition) kann der Geltungsbereich jedoch auch unterschiedliche Anteile haben, wie im folgenden Code:

#enthalten
mit Namensraumstd;

Vorlage<KlasseT,KlasseU> KlasseTheCla
{
öffentlich:
t num;
statischU ch;

LeereFunktion(Du Vater,const verkohlen *P)
{
Kosten << 'Es gibt ' <<Auf eins<< 'Bücher wert' <<Nein<<P<< ' Im Laden.' << ' ';
}
statisch LeereSpaß(U ch)
{
wenn (CH== 'zu')
Kosten << 'Offizielle statische Memberfunktion' << ' ';
}
};

inthauptsächlich()
{
TheCla<int,verkohlen>obj;
obj.Auf eins = 12;
obj.Funktion('$','500');

Rückkehr 0;
}

Namensverstecken

Ein Beispiel für das Verbergen von Namen tritt auf, wenn der Name desselben Objekttyps in einem verschachtelten Block erneut deklariert wird. Das folgende Programm veranschaulicht dies:

#enthalten
mit Namensraumstd;

Leerefn()
{
intwo= 3;
wenn (1==1)
{
intwo= 4;
Kosten<<wo<<' ';
}
Kosten<<wo<<' ';
}

inthauptsächlich()
{
fn();
Rückkehr 0;
}

Die Ausgabe ist:
4
3

Dies liegt daran, dass var im verschachtelten Block var im äußeren Block versteckt hat.

Möglichkeit zur Wiederholung der Erklärung im gleichen Umfang

Der Punkt der Deklaration ist, wo der Name (zum ersten Mal) in seinem Geltungsbereich eingeführt wird.

Funktionsprototyp
Unterschiedliche Entitäten, auch unterschiedlichen Typs, können normalerweise nicht im gleichen Gültigkeitsbereich deklariert werden. Ein Funktionsprototyp kann jedoch im selben Gültigkeitsbereich mehr als einmal deklariert werden. Das folgende Programm mit zwei Funktionsprototypen und entsprechender Funktionsdefinition veranschaulicht dies:

#enthalten
mit Namensraumstd;

Leerefn(intAuf eins);
Leerefn(intAuf eins);

Leerefn(intAuf eins)
{
Kosten<<Auf eins<<' ';
}

inthauptsächlich()
{
fn(5);

Rückkehr 0;
}

Das Programm funktioniert.

Überladene Funktionen
Überladene Funktionen sind Funktionen mit demselben Namen, aber unterschiedlichen Funktionssignaturen. Als weitere Ausnahme können überladene Funktionen gleichen Namens im gleichen Gültigkeitsbereich definiert werden. Das folgende Programm veranschaulicht dies:

#enthalten
mit Namensraumstd;

Leerefn(intAuf eins)
{
Kosten<<Auf eins<<' ';
}

Leerefn(schwebenNein)
{
Kosten<<Nein<<' ';
}

inthauptsächlich()
{
fn(5);
schwebenflt= 8,7;
fn(flt);

Rückkehr 0;
}

Die Ausgabe ist:
5
8,7

Die überladenen Funktionen wurden im globalen Geltungsbereich definiert.

Namespace-Bereich

Namespace Scope verdient einen eigenen Artikel. Der besagte Artikel wurde für diese Website, linuxhint.com, geschrieben. Geben Sie einfach die Suchbegriffe Namespace Scope in das Suchfeld dieser Site (Seite) ein und klicken Sie auf OK, und Sie erhalten den Artikel.

Umfang in verschiedenen Portionen

Die Klasse ist nicht das einzige Schema, bei dem der Geltungsbereich in verschiedenen Teilen liegen kann. Friend-Bezeichner, bestimmte Verwendungen des elaborierten-Typ-Bezeichners und using-Direktiven sind andere Schemata, bei denen der Geltungsbereich an anderen Stellen liegt – für Details siehe später.

Abschluss

Ein Geltungsbereich ist ein deklarativer Bereich. Ein deklarativer Bereich ist der größte Teil eines Programmtextes, in dem der Name einer Entität gültig ist. Es kann in Übereinstimmung mit bestimmten Programmierschemata in mehr als einen Teil unterteilt werden, wie zum Beispiel verschachtelte Blöcke. Die Teile, die keinen Deklarationspunkt haben, bilden den potentiellen Geltungsbereich. Der potenzielle Geltungsbereich kann die Deklaration aufweisen oder nicht.