2010-09-13 24 views
44

Ich würde gerne wissen, was ist der Unterschied zwischen statischen Variablen in einer Header-Datei vs deklariert in einer Klasse. Wenn eine statische Variable in einer Header-Datei deklariert ist, ist ihr Umfang auf die .h-Datei oder auf alle Einheiten beschränkt. Auch im Allgemeinen statische Variable wird in .cpp Datei initialisiert, wenn in einer Klasse deklariert, richtig? Das bedeutet also, dass der statische Variablenumfang auf 2 Kompilierungseinheiten beschränkt ist?Statische Variablen in C++

+5

Das 'statische' Schlüsselwort ist sehr überladen.Es bedeutet unterschiedlich an verschiedenen Orten. Deshalb ist es eine lustige Frage, die man bei Interviews stellen kann. – vrdhn

+0

Definitiv unter der Spitze, zusammen mit abstrakten Funktionen/abstrakten Klassen und Sachen wie öffentliche/geschützte/private Vererbung. ;-) – DevSolar

Antwort

67

Entschuldigung, wenn ich Ihre Fragen out-of-order beantworte, macht es einfacher, diesen Weg zu verstehen.

Wenn eine statische Variable in einer Header-Datei deklariert ist, ist ihr Umfang auf die .h-Datei oder auf alle Einheiten beschränkt.

Es gibt keine "Header-Datei-Bereich". Die Header-Datei wird in Quelldateien enthalten. Die Übersetzungseinheit ist die Quelldatei einschließlich der Text aus den Header-Dateien. Was immer Sie in eine Header-Datei schreiben, wird in jede Quelldatei kopiert.

Eine statische Variable, die in einer Headerdatei deklariert wird, ist also wie eine statische Variable in jeder einzelnen Quelldatei.

Da eine variable static erklärt auf diese Weise interne Bindung bedeutet, erhält jede Übersetzungseinheit #include ing Ihre Header-Datei seine eigenen, individuell Variable (die außerhalb Ihrer Übersetzungseinheit nicht sichtbar ist). Dies ist normalerweise nicht das, was Sie wollen.

Ich würde gerne wissen, was ist der Unterschied zwischen statischen Variablen in einer Header-Datei vs deklariert in einer Klasse.

In einer Klassendeklaration, static bedeutet, dass alle Instanzen der Klasse Aktien diese Membervariable; h., Sie könnten Hunderte von Objekten dieses Typs haben, aber jedes Mal, wenn eines dieser Objekte auf die Variable static (oder "Klasse") verweist, ist dies derselbe Wert für alle Objekte. Man könnte es sich als eine "globale Klasse" vorstellen.

Auch im Allgemeinen statische Variable wird in .cpp-Datei initialisiert, wenn in einer Klasse richtig erklärt?

Ja, eine (und nur ein) Übersetzungseinheit muss die Klassenvariable initialisieren.

Also bedeutet das statische Variable Umfang ist auf 2 Kompiliereinheiten begrenzt?

Wie gesagt:

  • Ein Header keine Übersetzungseinheit ist,
  • static bedeutet völlig verschiedene Dinge je nach Kontext.

Global static beschränkt den Gültigkeitsbereich auf die Übersetzungseinheit. Die Klasse static bedeutet global für alle Instanzen.

Ich hoffe, das hilft.

PS: Überprüfen Sie den letzten Absatz von Chubsdad Antwort, wie Sie nicht static in C++ zur Anzeige interne Bindung, sondern anonyme Namespaces verwendet werden soll. (Weil er recht hat ;-))

+6

"statisch bedeutet völlig verschiedene Dinge je nach Kontext." -> die Quelle der meisten Verwirrung darüber. Diese "nicht hinzufügen Stichworte" Mentalität ist wirklich nervig :( –

+0

@Matthieu M. Hängt von Ihrem Standpunkt. Für einige Kompatibilität zwischen C und C++ zu halten, ist es sehr vorteilhaft. Ich gebe jedoch zu, dass sie es ein wenig mit 'übertrieben haben static'. – DevSolar

+0

Ich weiß, dass die Kompatibilität notwendig war, sonst wäre die Sprache nicht so populär gewesen, aber sie hätten ein neues Schlüsselwort für C++ verwenden können, was bedeutet, dass sie außerhalb einer Klasse "non-keyword" haben könnten. Ich bin froh, dass sie das Schlüsselwort 'nullptr' in C++ 0x eingeführt haben. –

38

statische Variable in einer Header-Datei:

'common.h' sagen hat

static int zzz; 

Diese Variable 'zzz' hat interne Bindung (Dieselbe Variable kann nicht in anderen Übersetzungseinheiten zugegriffen werden kann). Jede Übersetzungseinheit, die enthält, hat ihr eigenes eindeutiges Objekt mit dem Namen 'zzz'.

statische Variable in einer Klasse:

statische Variable in einer Klasse ist nicht ein Teil des Subobjekt der Klasse. Es gibt nur eine Kopie eines statischen Datenelements, das von allen Objekten der Klasse gemeinsam genutzt wird.

$ 9.4.2/6 - „Statische Datenelemente einer Klasse im Namensraum Umfang haben externe Verknüpfung (3,5) .Ein lokale Klasse darf nicht statische Datenelemente haben.“

Sagen wir also, 'myclass.h' hat

struct myclass{ 
    static int zzz;  // this is only a declaration 
}; 

und myclass.cpp hat

#include "myclass.h" 

int myclass::zzz = 0   // this is a definition, 
           // should be done once and only once 

und "hisclass.cpp" hat

#include "myclass.h" 

void f(){myclass::zzz = 2;} // myclass::zzz is always the same in any 
           // translation unit 

und "ourclass.cpp" hat

#include "myclass.h" 
void g(){myclass::zzz = 2;} // myclass::zzz is always the same in any 
           // translation unit 

So sind Klasse statische Mitglieder nicht auf nur 2 Übersetzungseinheiten beschränkt. Sie müssen nur einmal in einer der Übersetzungseinheiten definiert werden.

Hinweis: Verwendung von ‚statischen‘ Dateigültigkeitsbereich Variable zu deklarieren ist veraltet und unbenannte Namespace ist eine überlegene alternative

+1

vielen Dank für eine nette Antwort. – brett

+1

"Jede Datei, die" ... enthält, ist ziemlich ungenau, da Headerdateien andere Headerdateien enthalten können. Lieber bei der Phrase * Übersetzungseinheit * oder * Übersetzungseinheit * bleiben. –

+3

und +1, um darauf hinzuweisen, dass anonyme Namespaces den Modifizierer "static" für globale Variablen ersetzen. –

12

eine statische Variable in einer Header-Datei außerhalb der Klasse deklarierte wäre file-scoped in jeder .c-Datei, die den Header enthält. Das bedeutet, dass in jeder der C-Dateien, in die Sie die Header-Datei einschließen, eine separate Kopie einer Variablen mit demselben Namen verfügbar ist.

Eine statische Klassenvariable hingegen ist class-scoped und die gleiche statische Variable ist für jede Kompilierungseinheit verfügbar, die den Header enthält, der die Klasse mit der statischen Variable enthält.