Ich habe festgestellt, dass einige meiner Funktionen in einer Klasse tatsächlich nicht auf das Objekt zugreifen, also habe ich sie erstellt static
. Dann sagte mir der Compiler, dass alle Variablen, auf die sie zugreifen, auch statisch sein müssen - na ja, bisher ziemlich verständlich. Ich habe eine Reihe von String-Variablen wie
string RE_ANY = "([^\\n]*)";
string RE_ANY_RELUCTANT = "([^\\n]*?)";
und so weiter in der Klasse. Ich habe sie dann alle gemacht, static const
weil sie sich nie ändern. Mein Programm wird jedoch nur kompiliert, wenn ich sie aus der Klasse verschiebe: Andernfalls beschwert sich MSVC ++ 2010 über "Innerhalb einer Klasse dürfen nur statische konstante Integralvariablen initialisiert werden".
Nun, das ist unglücklich. Gibt es eine Problemumgehung? Ich möchte sie in der Klasse lassen, zu der sie gehören.
quelle
const
und seinstatic
.const
bedeutet , dass es nicht ändernthis
... und es gibt keinethis
fürstatic
Methoden.string
weil es sich um eine Variablendefinition handelt, für die ein Typspezifizierer erforderlich ist, und der Typ iststring
. Sie können()
einen Deklarator umsetzen, wenn Sie möchten, es ändert nichts an der Bedeutung.Mike Seymour hat Ihnen die richtige Antwort gegeben, aber um hinzuzufügen ... Mit
C ++ können Sie in Ihrem Klassenkörper nur statische const-Integraltypen deklarieren und definieren , wie der Compiler sagt. Sie können also tatsächlich Folgendes tun:
class Foo { static const int someInt = 1; static const short someShort = 2; // etc. };
Und das können Sie mit keinem anderen Typ tun. In diesem Fall sollten Sie sie in Ihrer CPP-Datei definieren.
quelle
Statische Mitgliedsvariablen müssen in der Klasse deklariert und dann außerhalb definiert werden!
Es gibt keine Problemumgehung. Fügen Sie einfach die eigentliche Definition in eine Quelldatei ein.
Aus Ihrer Beschreibung geht hervor, dass Sie statische Variablen nicht richtig verwenden. Wenn sie sich nie ändern, sollten Sie stattdessen eine konstante Variable verwenden, aber Ihre Beschreibung ist zu allgemein, um etwas mehr zu sagen.
Statische Elementvariablen haben für jede Instanz Ihrer Klasse immer den gleichen Wert: Wenn Sie eine statische Variable eines Objekts ändern, ändert sich dies auch für alle anderen Objekte (und Sie können auch ohne Instanz der Klasse darauf zugreifen - dh: ein Objekt).
quelle
extern
die in anderen Quelldateien definierten Variablen deklarieren müssen .struct A { static int x; };
und versuchen,A::x
ohne Definitionint A::x;
in einer Quelldatei darauf zuzugreifen , wird Ihr Code nicht verknüpft.Seit C ++ 11 kann es innerhalb einer Klasse mit durchgeführt werden
constexpr
.class stat { public: // init inside class static constexpr double inlineStaticVar = 22; };
Auf die Variable kann jetzt zugegriffen werden mit:
quelle
constexpr char RE_ANY[] = "([^\\n]*)";
oderconstexpr std::string_view RE_ANY("([^\\n]*)", 9);
.Ich halte es für erwähnenswert, dass eine statische Variable nicht mit einer konstanten Variablen identisch ist.
Verwenden einer konstanten Variablen in einer Klasse
struct Foo{ const int a; Foo(int b) : a(b){} }
und wir würden es so erklären
fooA = new Foo(5); fooB = new Foo(10); // fooA.a = 5; // fooB.a = 10;
Für eine statische Variable
struct Bar{ static int a; Foo(int b){ a = b; } } Bar::a = 0; // set value for a
welches so benutzt wird
barA = new Bar(5); barB = new Bar(10); // barA.a = 10; // barB.a = 10; // Bar::a = 10;
Sie sehen, was hier passiert. Die konstante Variable, die zusammen mit jeder Instanz von Foo instanziiert wird, da Foo instanziiert wird, hat für jede Instanz von Foo einen eigenen Wert und kann von Foo überhaupt nicht geändert werden.
Wo wie bei Bar ist dies nur ein Wert für Bar :: a, egal wie viele Instanzen von Bar erstellt werden. Sie alle teilen diesen Wert. Sie können auch darauf zugreifen, wenn sie Instanzen von Bar sind. Die statische Variable hält sich auch an Regeln für öffentlich / privat, sodass Sie festlegen können, dass nur Instanzen von Bar den Wert von Bar :: a lesen können.
quelle
new
. ;-)Nur um die anderen Antworten zu ergänzen. Um ein komplexes statisches Element zu initialisieren , können Sie dies wie folgt tun:
Deklarieren Sie Ihr statisches Mitglied wie gewohnt.
// myClass.h class myClass { static complexClass s_complex; //... };
Erstellen Sie eine kleine Funktion, um Ihre Klasse zu initialisieren, wenn dies nicht trivial ist. Dies wird nur einmal aufgerufen, wenn das statische Element initialisiert wird. (Beachten Sie, dass der Kopierkonstruktor von complexClass verwendet wird, daher sollte er gut definiert sein.)
//class.cpp #include myClass.h complexClass initFunction() { complexClass c; c.add(...); c.compute(...); c.sort(...); // Etc. return c; } complexClass myClass::s_complex = initFunction();
quelle
Einige Antworten scheinen etwas irreführend zu sein .
Du musst nicht ...
.cpp
Datei zum Initialisieren, da dies in derselben Header- Datei erfolgen kann.Sie können sogar ein statisches Objekt im selben Klassenbereich wie eine normale Variable mit dem
inline
Schlüsselwort initialisieren .Initialisieren Sie ohne Werte in derselben Datei
#include <string> class A { static std::string str; static int x; }; std::string A::str; int A::x;
Initialisieren Sie mit Werten in derselben Datei
#include <string> class A { static std::string str; static int x; }; std::string A::str = "SO!"; int A::x = 900;
Initialisieren Sie im selben Klassenbereich mit dem
inline
Schlüsselwort#include <string> class A { static inline std::string str = "SO!"; static inline int x = 900; };
quelle
inline
und alle Verknüpfungsfehler sind verschwunden.-std=c++17
oder-std=c++20
usw.Wenn Sie die statische Variable in Ihrer Header-Datei initialisieren möchten (anstelle einer * .cpp-Datei, die Sie möglicherweise benötigen, wenn Sie sich an eine "nur Header" -Idiom halten), können Sie das Initialisierungsproblem mithilfe von a umgehen Vorlage. Statische Variablen mit Vorlagen können in einem Header initialisiert werden, ohne dass mehrere Symbole definiert werden müssen.
Ein Beispiel finden Sie hier:
Statische Elementinitialisierung in einer Klassenvorlage
quelle
Verschieben Sie optional alle Ihre Konstanten in die CPP-Datei ohne Deklaration in der H-Datei. Verwenden Sie einen anonymen Namespace, um sie über das cpp-Modul hinaus unsichtbar zu machen.
// MyClass.cpp #include "MyClass.h" // anonymous namespace namespace { string RE_ANY = "([^\\n]*)"; string RE_ANY_RELUCTANT = "([^\\n]*?)"; } // member function (static or not) bool MyClass::foo() { // logic that uses constants return RE_ANY_RELUCTANT.size() > 0; }
quelle