Die Klasse statische Variablen im Header deklariert sein kann, aber muss in einer CPP-Datei definiert werden. Dies liegt daran, dass es nur eine Instanz einer statischen Variablen geben kann und der Compiler nicht entscheiden kann, in welcher generierten Objektdatei er abgelegt werden soll. Stattdessen müssen Sie die Entscheidung treffen.
Um die Definition eines statischen Wertes mit der Deklaration in C++ 11 zu behalten, kann eine verschachtelte statische Struktur verwendet werden. In diesem Fall ist das statische Element eine Struktur und muss in einer CPP-Datei definiert werden, aber die Werte sind in der Kopfzeile.
class A
{
private:
static struct _Shapes {
const std::string RECTANGLE {"rectangle"};
const std::string CIRCLE {"circle"};
} shape;
};
Statt einzelne Mitglieder die gesamte statische Struktur der Initialisierung in CPP initialisiert wird:
A::_Shapes A::shape;
Die Werte werden zugegriffen mit
A::shape.RECTANGLE;
oder - da die Mitglieder privat sind und sind nur für die Verwendung von A - mit
shape.RECTANGLE;
bestimmt
Beachten Sie, dass diese Lösung immer noch das Problem in der Reihenfolge Initialisierung der statischen Variablen leidet. Wenn ein statischer Wert für verwendet wird, um eine andere statische Variable zu initialisieren, wird die erste möglicherweise noch nicht initialisiert, .
// file.h
class File {
public:
static struct _Extensions {
const std::string h{ ".h" };
const std::string hpp{ ".hpp" };
const std::string c{ ".c" };
const std::string cpp{ ".cpp" };
} extension;
};
// file.cpp
File::_Extensions File::extension;
// module.cpp
static std::set<std::string> headers{ File::extension.h, File::extension.hpp };
In diesem Fall werden die statischen Variablen headers enthält entweder { ""} oder { ".h", ".hpp"}, in Abhängigkeit von der Reihenfolge der Initialisierung durch den Linker erstellt.
Wie von @ abyss.7 erwähnt, können Sie auch constexpr
verwenden, wenn der Wert der Variablen zur Kompilierzeit berechnet werden kann. Aber wenn Sie erklären, um Ihre Strings mit static constexpr const char*
und Ihr Programm verwendet std::string
sonst wird es ein Overhead, weil ein neues std::string
Objekt wird jedes Mal, wenn Sie eine solche Konstante verwenden erstellt werden:
class A {
public:
static constexpr const char* STRING = "some value";
};
void foo(const std::string& bar);
int main() {
foo(A::STRING); // a new std::string is constructed and destroyed.
}
Danke für all Ihre tollen Antworten! Es lebe SO! –
Kann mir bitte jemand sagen, was ein integraler Typ ist? Vielen Dank. –
Integrale Typen beziehen sich auf Typen, die ganze Zahlen darstellen. Siehe http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fintvar.htm – bleater