Was genau bedeutet „statisch“, wenn sie „globale“ Variablen in C ++ deklarieren?

StackOverflow https://stackoverflow.com/questions/3416728

  •  26-09-2019
  •  | 
  •  

Frage

Dies ist eine Erweiterung des Umfangs von a Vorherige Frage von mir.

Was genau ist "statisch", wie wird es verwendet und was ist der Zweck der Verwendung von "statischer" beim Umgang mit C ++?

Vielen Dank.

War es hilfreich?

Lösung

Das Schlüsselwort static hat je nach Kontext unterschiedliche Bedeutungen in C ++.

Wenn Sie eine freie Funktion oder eine globale Variable deklarieren, bedeutet dies, dass die Funktion außerhalb dieser einzelnen Übersetzungseinheit nicht verfügbar sein soll:

// test.cpp
static int a = 1;
static void foo() {}

Wenn das Ergebnis des Zusammenstellens dieser Übersetzungseinheit mit einer anderen Übersetzungseinheit mit Symbolen verknüpft ist a und foo Es wird die einzige Definitionsregel nicht wie in dieser bestimmten Übersetzungseinheit verstoßen a und foo sind Privatgelände Symbole. Diese Verwendung wurde von unbenannten Namespaces veraltet.

// test2.cpp
namespace {
   static int a = 1;
   static void foo() {}
}

Bei der Erklärung einer lokalen Variablen innerhalb einer Funktion bedeutet dies, dass sich die Lebensdauer der Variablen vom ersten Aufruf zur Funktion bis zum Ende des Programms und nicht nur für die Dauer des Anrufs erstreckt:

int foo() {
   static int counter = 0;
   return ++counter;
}
int main() {
  for ( int i = 0; i < 10; ++i ) { 
     std::cout << foo() << std::endl;
  }
}

Im vorherigen Code, counter wird einmal initialisiert, wenn foo wird zum ersten Mal aufgerufen, aber die Variable überlebt die Funktion und hält den Wert über verschiedene Funktionsaufrufe hinweg. Der vorherige Code druckt "1 2 3 4 ... 10". Wenn die Variable nicht deklariert wurde static Dann wäre der Ausgang "1 1 1 ... 1".

Innerhalb eines Klassenbereichs, static bedeutet, dass das Mitglied ein Mitglied der Klasse ist und nicht eines bestimmten Falles. Diese Verwendung entspricht der Verwendung in Ihrer anderen Frage: Die Verwendung dieses bestimmten Mitglieds ist nicht an ein bestimmtes Objekt gebunden.

struct test {
   int x;
   static int y;
};
int test::y;       // need to define it in one translation unit
int main() {
   // test::x = 5; // !error cannot access a non-static member variable
                   // without an instance
   test::y = 5;    // ok
   test t, other;
   t.x = 10;       // ok
   t.y = 15;       // ok, the standard allows calling a static member through
                   // an instance, but this is the same as test::y
}

In diesem Fall das Mitglied x ist ein nicht statisches Mitgliedsattribut, und als solches gibt es eine andere x Für jede Instanz der Klasse. Im Beispielprogramm t.x und other.x Beziehen Sie sich auf verschiedene ganze Zahlen. Auf der anderen Seite y ist static und so gibt es eine einzelne Instanz von test::y im Programm. Auch wenn der Standard anrufen kann t.y und other.y Beide Verwendungen beziehen sich auf dieselbe Variable. Gleiches gilt für Mitgliedermethoden. Wenn sie statisch sind, sind sie Methoden auf Klassenebene und können ohne Instanz aufgerufen werden, während sie, wenn sie nicht statisch sind, auf eine konkrete Instanz angewendet werden und die a.b oder a->b Syntax muss verwendet werden.

Diese Verwendung von static ähnelt der Verwendung desselben Schlüsselworts in Java, während die beiden anderen in dieser Sprache nicht vorhanden sind. Es wird eine Verwendung des Schlüsselworts in Java verwendet, das nicht in C ++ vorhanden ist, und das ist die Verwendung statischer Klasseninitialisierer (ein Codeblock auf Klassenebene, umgeben von von static { ... }). In Java wird dieser Codeblock ausgeführt, wenn die Klasse geladen wird und nur einmal. Die Initialisierung statischer Mitgliedsvariablen in C ++ muss im Initialisierer der Variablendefinition erfolgen.

Andere Tipps

Dies bedeutet, dass die Variable lokal zu einer Übersetzungseinheit (einfach in eine einzelne Quelldatei) ist und von außen nicht zugegriffen werden kann. Diese Verwendung von static wird tatsächlich im aktuellen C ++ - Standard veraltet - stattdessen sollen Sie anonyme Namespaces verwenden:

static int x = 0;    

sollte sein:

namespace {
    int x = 0;    
}

Dieses Zeug scheint ziemlich gut bedeckt zu sein hier.

Um zu paraphrasieren, gibt es 2 Verwendungen in C

  1. Verhindern Sie die Verwendung einer globalen Variablen außerhalb des Umfangs der Datei, die sie definiert.
  2. Ermöglichen

    int getNextId () {static int id = 0; Return ID ++; }

C ++ erbt beide und fügt zwei eigene Verwendungen hinzu.

  1. Statische Mitgliedsvariablen: Variablen, die alle Instanzen einer Klasse "gemeinsam genutzt" sind und auch ohne Bezug auf eine Instanz der Klasse zugreifen können. Shared scheint das falsche Wort zu sein, aber im Wesentlichen glaube ich, dass das Ergebnis ist, dass jeder Hinweis auf eine statische Mitgliedsvariable auf denselben Speicherort verweist.
  2. Statische Methoden: Methoden, die auf eine bestimmte Instanz der Klasse aufgerufen werden können, die sie definiert.

Statisch bedeutet im Grunde, dass eine Variable an die Lebensdauer des Programms und keine bestimmte Funktion oder Klasseninstanz gebunden ist. Wann solltest du es benutzen? Nicht. Was ist der Zweck? Meistens Daten debuggen.

Wenn Sie in C ++ statische Daten verwenden, haben Sie es im Allgemeinen falsch gemacht. Es gibt Zeiten, in denen es angemessen ist, aber sie sind sehr selten.

Wenn statisch in einer Klasse in C ++ verwendet wird, bedeutet dies mehr oder weniger dasselbe wie in Java. Für Variablen bedeutet dies, dass für alle Klassen und für Funktionen eine Instanz der Variablen vorhanden ist, dies bedeutet, dass die Funktion überhaupt nicht auf diesen Zeiger zugreift.

In C und C ++, wenn statisch für eine globale Variable oder Funktion verwendet wird, bedeutet dies, dass die Variable nur in der aktuellen C- oder C ++ -Datei referenziert werden kann. Mit anderen Worten darf der Compiler keine Verlagerungssymbole für die Variable oder Funktion generieren.

Wenn statisch neben einer Variablen in einer lokalen Funktion verwendet wird, bedeutet dies, dass die Variable nicht aus dem Umfang ausgeht, sondern ihren Wert vom Funktionsanruf auf Funktion beibehält. Die Variable wird effektiv zu einer globalen Variablen, auf die nur aus der angegebenen Funktion zugegriffen werden kann.

Statische Klassenmitglieder sind Daten und Funktionen, die mit der Klasse selbst und nicht mit den Objekten der Klasse verbunden sind.

Im folgenden Beispiel verfügt die Class Fred über ein statisches Datenmitglied x_ und ein Instanzdatenmitglied y_. Es gibt nur eine Kopie von Fred :: x_, unabhängig davon, wie viele Fred -Objekte erstellt werden (einschließlich keiner Fred -Objekte), aber es gibt ein y_ pro Fred -Objekt. Somit soll X_ der Klasse zugeordnet sein und Y_ einem individuellen Objekt der Klasse zugeordnet sein. In ähnlicher Weise hat der Class Fred eine statische Mitgliedsfunktion f () und eine Instanzelementfunktion G ().

class Fred {
    public:
        static void f() throw();                           <-- 1
        void g() throw();                                  <-- 2
    protected:
        static int x_;                                     <-- 3
        int y_;                                            <-- 4
};

(1) Mitgliedsfunktion, die der Klasse zugeordnet ist

(2) Mitgliedsfunktion, die einem einzelnen Objekt der Klasse zugeordnet ist

(3) Datenmitglied, die der Klasse zugeordnet sind

(4) Datenmitglied, das einem einzelnen Objekt der Klasse zugeordnet ist

Verwendungszweck:

Wenn Sie die Anzahl der Instanzen einer erstellten Klasse einhalten möchten, verwenden Sie statische Variable. Zum Beispiel kann in einer Automobilklasse jede Autoinstanz eine eindeutige Seriennummer haben (in diesem Fall), und das Unternehmen möchte möglicherweise die Anzahl der produzierten Autos verfolgen (_x in diesem Fall).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top