C++

C++-Qualifizierer und Speicherklassenspezifizierer

C++-Qualifizierer und Speicherklassenspezifizierer

CV steht für Constant-Volatile. Die Deklaration eines Objekts, dem kein const und/oder volatile vorangestellt ist, ist ein cv-unqualifizierter Typ. Andererseits ist die Deklaration eines Objekts, dem const und/oder volatile vorangestellt ist, ein CV-qualifizierter Typ. Wenn ein Objekt als const deklariert wird, kann der Wert an seiner Position nicht geändert werden. Eine flüchtige Variable ist eine Variable, deren Wert unter dem Einfluss des Programmierers steht und daher vom Compiler nicht geändert werden kann.Speicherklassenspezifizierer beziehen sich auf die Lebensdauer, den Ort und die Art und Weise, wie ein Typ existiert. Speicherklassenspezifizierer sind statisch, veränderlich, thread_local und extern.

In diesem Artikel werden C++-Qualifizierer und Speicherklassenspezifizierer erläutert. Daher sind einige Vorkenntnisse in C++ praktisch, um den Artikel wirklich zu schätzen.

Artikelinhalt:

Qualifikationen:

const

Ein als konstant deklariertes Objekt ist ein Objekt, dessen Speicher (Ort) nicht geändert werden kann. Zum Beispiel in der Aussage:

int const theInt = 5;

Der Wert von 5 im Speicher für theInt kann nicht geändert werden.

flüchtig

Betrachten Sie die folgende Aussage:

int portVal = 26904873;

Compiler stören manchmal den Wert einer Variablen in der Hoffnung, das Programm zu optimieren. Der Compiler kann den Wert einer Variablen als konstant halten, wenn er nicht konstant sein soll. Objektwerte, die mit speicherabgebildeten IO-Ports oder Interrupt-Service-Routinen von Peripheriegeräten zu tun haben, können vom Compiler beeinflusst werden. Um solche Interferenzen zu vermeiden, machen Sie die Variable flüchtig, wie zum Beispiel:

int volatile portVal;
portVal = 26904873;
oder wie:
int volatile portVal = 26904873;

Kombination von const und volatile:

const und volatile können wie folgt in einer Anweisung vorkommen:

int const volatile portVal = 26904873;

Lebenslauf-Qualifizierer

Eine Variable, der const und/oder volatile vorangestellt ist, ist ein CV-qualifizierter Typ. Eine Variable, der weder const noch volatile oder beides vorangestellt ist, ist ein CV-unqualifizierter Typ.

Bestellung:

Ein Typ kann mehr Lebenslauf-qualifiziert sein als ein anderer:

Es ist noch nicht entschieden, ob const und volatile gleichrangig sind.

Array und instanziiertes Objekt:

Wenn ein Array wie in der folgenden Anweisung als konstant deklariert wird, bedeutet dies, dass der Wert jedes Elements des Arrays nicht geändert werden kann:

const char arr[] = 'a', 'b', 'c', 'd';

Ob es ein 'a', 'b', 'c' oder 'd' ist, es kann immer noch nicht in einen anderen Wert (Zeichen) geändert werden.

Ähnliches gilt für ein instanziiertes Objekt einer Klasse. Betrachten Sie das folgende Programm:

#einschließen
Verwenden von Namespace-Std;
Klasse Cla

Öffentlichkeit:
char ch0 = 'a';
char ch1 = 'b';
char ch2 = 'c';
char ch3 = 'd';
;
int main()

const Cla obj;
0 zurückgeben;

Aufgrund der Aussage „const Cla obj;“ mit const in der main()-Funktion können weder 'a' noch 'b' noch 'c' noch 'd' in einen anderen Wert geändert werden.

Speicherklassenspezifizierer:

Speicherklassenspezifizierer sind statisch, veränderbar, thread_local und extern.

Das statischer Speicherklassenspezifizierer

Der statische Speicherklassenspezifizierer ermöglicht es der Variablen, nach dem Durchlaufen ihres Gültigkeitsbereichs zu leben, aber es kann nicht direkt darauf zugegriffen werden.

Das folgende Programm veranschaulicht dies mit einer rekursiven Funktion:

#einschließen
Verwenden von Namespace-Std;
int-Funktion()

statisch int stac = 10;
cout << stac < 50)

cout << '\n';
0 zurückgeben;

Funktion();

int main()

Funktion();
0 zurückgeben;

Die Ausgabe ist:

10 20 30 40 50

Wenn eine statische Variable bei ihrer ersten Deklaration nicht initialisiert wird, nimmt sie den Standardwert für ihren Typ an.

Der statische Bezeichner kann auch mit Mitgliedern einer Klasse verwendet werden; die verwendung hier ist anders. Hier ermöglicht es den Zugriff auf das Mitglied ohne Instanziierung für das Objekt.

Das folgende Programm veranschaulicht dies für ein Datenelement:

#einschließen
Verwenden von Namespace-Std;
Klasse Cla

Öffentlichkeit:
statische const int num = 8;
;
int main()

cout << Cla::num << '\n';
0 zurückgeben;

Die Ausgabe ist:

8

Der statische Datenmember muss konstant sein. Beachten Sie, dass die Verwendung des Bereichsauflösungsoperators für den Zugriff auf die statische Variable außerhalb ihres Bereichs (in der Hauptfunktion).

Das folgende Programm veranschaulicht die Verwendung von „static“ für eine Memberfunktion:

#einschließen
Verwenden von Namespace-Std;
Klasse Cla

Öffentlichkeit:
statische void-Methode ()

cout << "Of static member function!" << '\n';

;
int main()

Cla::Methode();
0 zurückgeben;

Die Ausgabe ist:

Von statischer Memberfunktion!

Beachten Sie, dass die Verwendung des Bereichsauflösungsoperators für den Zugriff auf die statische Memberfunktion außerhalb ihres Bereichs (in der Hauptfunktion).

Der veränderliche Spezifizierer

Denken Sie von oben daran, dass, wenn ein instanziiertes Objekt mit const beginnt, der Wert eines seiner normalen Datenelemente nicht geändert werden kann. Und damit ein solches Datenelement geändert werden kann, muss es als veränderlich deklariert werden.

Das folgende Programm veranschaulicht dies:

#einschließen
Verwenden von Namespace-Std;
Klasse Cla

Öffentlichkeit:
char ch0 = 'a';
char ch1 = 'b';
veränderbares Zeichen ch2 = 'c';
char ch3 = 'd';
;
int main()

const Cla obj;
obj.ch2 = 'z';
cout << obj.ch0 << " << obj.ch1 << " << obj.ch2 << " << obj.ch3 << " << '\n';
0 zurückgeben;

Die Ausgabe ist:

'a'b'z'd'

Der thread_local-Spezifizierer

Im normalen Ablauf eines Programms wird ein Codesegment ausgeführt, dann das nächste Codesegment, gefolgt von einem weiteren Codesegment und so weiter. Das ist ein Thread; der Hauptthread. Wenn zwei Codesegmente gleichzeitig ausgeführt werden (gleiche Dauer), wird ein zweiter Thread benötigt. Das Ergebnis des zweiten Threads kann sogar vor dem Hauptthread fertig sein.

Die Funktion main() ist wie der Hauptthread. Ein Programm kann für ein solches asynchrones Verhalten mehr als zwei Threads haben.

Der zweite Thread benötigt einen Scope (Block Scope), um zu funktionieren. Dies wird typischerweise durch den Funktionsumfang bereitgestellt, eine Funktion. Eine Variable in einem äußeren Gültigkeitsbereich, die im Gültigkeitsbereich des zweiten Threads zu sehen ist.

Das folgende kurze Programm veranschaulicht die Verwendung des Spezifizierers thread_local:

#einschließen
#einschließen
Verwenden von Namespace-Std;
thread_local int inter = 1;
void thread_function()

inter = inter + 1;
cout << inter << "nd thread\n";

int main()

thread thr(&thread_function); // thr beginnt zu laufen
cout << inter << "st or main thread\n";
durch.beitreten(); // Hauptthread wartet auf das Ende des Threads, thrr
0 zurückgeben;

Die Ausgabe ist:

1. oder Hauptthread
2. Thread

Die Variable inter, der thread_local vorangestellt ist, bedeutet, dass inter in jedem Thread eine separate Instanz hat. Und dass es in verschiedenen Threads geändert werden kann, um unterschiedliche Werte zu haben. In diesem Programm wird ihm im Hauptthread der Wert 1 zugewiesen und im zweiten Thread auf den Wert 2 geändert.

Ein Thread benötigt ein spezielles Objekt, um zu funktionieren. Für dieses Programm ist die Bibliothek von "#include" enthalten ” hat eine Klasse namens Thread, aus der das Objekt thr instanziiert wurde. Der Konstruktor für dieses Objekt nimmt eine Referenz auf die Thread-Funktion als Argument. Der Name der Thread-Funktion in diesem Programm ist thread_function().

Die Memberfunktion join() für das spezielle Objekt lässt den Hauptthread an seiner verwendeten Position warten, bis der zweite Thread die Ausführung beendet hat, bevor er mit der Ausführung fortfährt. Andernfalls kann die Funktion main() beendet werden, ohne dass der (zweite) Thread lieferte sein Ergebnis.

Der externe Spezifizierer

Einfach ausgedrückt, für eine Deklaration wird der Variablen oder Funktion kein Speicher zugewiesen, während für eine Definition Speicher zugewiesen wird. Das reservierte Wort extern ermöglicht, dass eine globale Variable oder Funktion in einer Datei deklariert, aber in einer anderen definiert wird. Solche Dateien werden Übersetzungseinheiten für die gesamte C++-Anwendung genannt.

Geben Sie das folgende Programm ein und speichern Sie es unter dem Dateinamen mainFile:

#einschließen
Verwenden von Namespace-Std;
int myInt;
const char ch;
void myFn();
int main()

meinFn();
0 zurückgeben;

Die Variable myInt, die konstante Variable ch und die Funktion myFn() wurden ohne Definition deklariert.

Geben Sie das folgende Programm mit den Definitionen ein und speichern Sie es unter dem Dateinamen otherFile im selben Verzeichnis:

#einschließen
Verwenden von Namespace-Std;
int myInt = 10;
const char ch = 'c';
void myFn()

cout << "myFn() says " << myInt << " and " << ch <<'\n';

Versuchen Sie, die Anwendung am Terminal (DOS-Eingabeaufforderung) mit dem folgenden Befehl zu kompilieren, und beachten Sie, dass sie möglicherweise nicht kompiliert wird:

g++ Hauptdatei.cpp otherFile.cpp -o komplett.exe

Stellen Sie nun den drei Deklarationen in mainFile das Wort „extern“ wie folgt voran:

extern int myInt;
extern const char ch;
extern void myFn();

MainFile erneut speichern. Stellen Sie den Antrag zusammen mit:

g++ Hauptdatei.cpp otherFile.cpp -o komplett.exe

(So ​​werden separate Dateien für dieselbe Anwendung in C++ kompiliert)

Und es sollte kompilieren. Führen Sie nun die Anwendung aus, vervollständigen Sie.exe, und die Ausgabe sollte sein:

myFn() sagt 10 und c

Beachten Sie, dass mit der Verwendung von „extern“ eine konstante Variable in einer Datei deklariert, aber in einer anderen definiert werden kann. Bei Funktionsdeklarationen und -definitionen in verschiedenen Dateien ist die Verwendung von extern optional.

Wann sollte man extern verwenden?? Verwenden Sie es, wenn Sie keine Header-Dateien mit globalen Deklarationen haben.

„extern“ wird auch bei Template-Deklarationen verwendet - siehe später.

Fazit:

Eine Variable, der const und/oder volatile vorangestellt ist, ist ein CV-qualifizierter Typ. Eine Variable, der weder const noch volatile oder beides vorangestellt ist, ist ein CV-unqualifizierter Typ.

Speicherklassenspezifizierer sind statisch, veränderbar, thread_local und extern. Diese beeinflussen die Lebensdauer (Dauer), den Ort und die Art der Verwendung von Variablen in einer Anwendung an.

Installieren Sie den neuesten Dolphin Emulator für Gamecube & Wii unter Linux
Mit dem Dolphin Emulator können Sie Ihre ausgewählten Gamecube- und Wii-Spiele auf Linux-Personalcomputern (PC) spielen. Als frei verfügbarer Open-So...
So verwenden Sie die GameConqueror-Cheat-Engine unter Linux
Der Artikel enthält eine Anleitung zur Verwendung der GameConqueror-Cheat-Engine unter Linux. Viele Benutzer, die Spiele unter Windows spielen, verwen...
Beste Spielkonsolen-Emulatoren für Linux
Dieser Artikel listet beliebte Spielekonsolen-Emulationssoftware auf, die für Linux verfügbar ist. Emulation ist eine Softwarekompatibilitätsschicht, ...