Die statischen Klassenvariablen können im Header deklariert werden , müssen jedoch 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 welche generierte Objektdatei sie eingefügt werden soll, sodass Sie stattdessen die Entscheidung treffen müssen.
Um die Definition eines statischen Werts mit der Deklaration in C ++ 11 beizubehalten, kann eine verschachtelte statische Struktur verwendet werden. In diesem Fall ist das statische Element eine Struktur und muss in einer CPP-Datei definiert werden, die Werte befinden sich jedoch im Header.
class A
{
private:
static struct _Shapes {
const std::string RECTANGLE {"rectangle"};
const std::string CIRCLE {"circle"};
} shape;
};
Anstatt einzelne Elemente zu initialisieren, wird die gesamte statische Struktur in .cpp initialisiert:
A::_Shapes A::shape;
Auf die Werte wird mit zugegriffen
A::shape.RECTANGLE;
oder - da die Mitglieder privat sind und nur von A verwendet werden sollen - mit
shape.RECTANGLE;
Beachten Sie, dass diese Lösung immer noch unter dem Problem der Reihenfolge der Initialisierung der statischen Variablen leidet. Wenn ein statischer Wert zum Initialisieren einer anderen statischen Variablen verwendet wird, 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 enthalten die statischen Variablen- Header je nach der vom Linker erstellten Initialisierungsreihenfolge entweder {""} oder {".h", ".hpp"}.
Wie in @ abyss.7 erwähnt, können Sie auch verwenden, constexpr
wenn der Wert der Variablen zur Kompilierungszeit berechnet werden kann. Wenn Sie jedoch Ihre Zeichenfolgen mit deklarieren static constexpr const char*
und Ihr Programm std::string
anderweitig verwendet , entsteht ein Overhead, da std::string
jedes Mal, wenn Sie eine solche Konstante verwenden, ein neues Objekt erstellt wird:
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.
}