Wie initialisiere ich ein statisches const-Mitglied in C ++?
73
Ist es möglich, einen statischen const-Wert außerhalb des Konstruktors zu initialisieren? Kann es an derselben Stelle initialisiert werden, an der Mitgliedererklärungen gefunden werden?
Ja, was Sie haben, funktioniert (aber nur für integrale Typen).
Onkel Bens
3
Ich wollte nur hinzufügen, dass dies staticnichts mit Konstruktoren zu tun hat, da staticMitglieder nicht spezifisch für eine bestimmte Instanz sind und außerhalb dieser existieren.
Am
Tatsächlich müssen Sie die Konst-Statik außerhalb eines Klassenkonstruktors initialisieren. Sonst wäre es keine konstante Statik. DUCY?
JA können Sie aber nur für int-Typen. Wenn Sie möchten, dass Ihr statisches Mitglied ein anderer Typ ist, müssen Sie es irgendwo in einer CPP-Datei definieren.
classA{private:
staticconstint a = 4; // validstaticconststd::string t ; // can't be initialized here
...
...
};
// in a cpp file where the static variable will exist conststd::string A::t = "this way it works";
Beachten Sie außerdem, dass diese Regel in C ++ 11 entfernt wurde. Jetzt können Sie (mit einem Compiler, der die Funktion bereitstellt) das, was Sie möchten, direkt in der Klassenmitgliedsdeklaration initialisieren.
@anarhikos - Die In-Class-Initialisierung funktioniert nur für integrale Typen. doubleist kein integraler Typ.
Brian Neal
1
@anrhikos: Deshalb solltest du nicht innerhalb der Klasse definieren. Sie sollten außerhalb der Klasse als eine Frage der Praxis definieren (siehe meine Antwort)
Was ist, wenn ich keinen Wert zuweisen möchte? Was ist, wenn nur der Standardkonstruktor ausgeführt werden soll? Ich erhalte Fehler beim erneuten Deklarieren der Variablen außerhalb der Klasse, wenn ich nichts zuweise.
Ben Farmer
1
@anarhikos, müssen Sie inline vor statischen const (C ++ 17) oder constexpr
Die Deklaration eines statischen Datenelements in der Mitgliederliste einer Klasse ist keine Definition. Sie müssen das statische Element außerhalb der Klassendeklaration im Namespace-Bereich definieren. Zum Beispiel:
classX
{public:
staticint i;
};
int X::i = 0; // definition outside class declaration
Sobald Sie ein statisches Datenelement definiert haben, ist es vorhanden, obwohl keine Objekte der Klasse des statischen Datenelements vorhanden sind. Im obigen Beispiel sind keine Objekte der Klasse X vorhanden, obwohl das statische Datenelement X :: i definiert wurde.
Statische Datenelemente einer Klasse im Namespace-Bereich sind extern verknüpft. Der Initialisierer für ein statisches Datenelement befindet sich im Bereich der Klasse, die das Element deklariert.
Ein statisches Datenelement kann von einem beliebigen Typ sein, mit Ausnahme von void oder void, die mit const oder volatile qualifiziert sind. Sie können ein statisches Datenelement nicht als veränderbar deklarieren.
Sie können nur eine Definition eines statischen Elements in einem Programm haben. Unbenannte Klassen, Klassen in unbenannten Klassen und lokale Klassen dürfen keine statischen Datenelemente haben.
Statische Datenelemente und ihre Initialisierer können auf andere statische private und geschützte Mitglieder ihrer Klasse zugreifen. Das folgende Beispiel zeigt, wie Sie statische Elemente mit anderen statischen Elementen initialisieren können, obwohl diese Elemente privat sind:
classC {staticint i;
staticint j;
staticint k;
staticint l;
staticint m;
staticint n;
staticint p;
staticint q;
staticint r;
staticint s;
staticintf(){ return0; }
int a;
public:
C() { a = 0; }
};
C c;
int C::i = C::f(); // initialize with static member functionint C::j = C::i; // initialize with another static data memberint C::k = c.f(); // initialize with member function from an objectint C::l = c.j; // initialize with data member from an objectint C::s = c.a; // initialize with nonstatic data memberint C::r = 1; // initialize with a constant valueclassY :private C {} y;
int C::m = Y::f();
int C::n = Y::r;
int C::p = y.r; // errorint C::q = y.f(); // error
Die Initialisierungen von C :: p und C :: q verursachen Fehler, da y ein Objekt einer Klasse ist, die privat von C abgeleitet ist und deren Mitglieder Mitgliedern von C nicht zugänglich sind.
Wenn ein statisches Datenelement vom Typ const-Integral oder const-Aufzählung ist, können Sie in der Deklaration des statischen Datenelements einen konstanten Initialisierer angeben. Dieser konstante Initialisierer muss ein integraler konstanter Ausdruck sein. Beachten Sie, dass der Konstanteninitialisierer keine Definition ist. Sie müssen das statische Element weiterhin in einem umschließenden Namespace definieren. Das folgende Beispiel zeigt dies:
Danke @Chubsdad fürs Teilen! Es war sehr schwer, die richtige Syntax zu finden.
Benutzer
7
Sie können statische Elemente in Konstruktoren nicht initialisieren. Integrale Typen können Sie bei ihrer Deklaration inline initialisieren. Andere statische Elemente müssen (in einer .cpp) Datei definiert sein:
static
nichts mit Konstruktoren zu tun hat, dastatic
Mitglieder nicht spezifisch für eine bestimmte Instanz sind und außerhalb dieser existieren.Antworten:
JA können Sie aber nur für int-Typen. Wenn Sie möchten, dass Ihr statisches Mitglied ein anderer Typ ist, müssen Sie es irgendwo in einer CPP-Datei definieren.
class A{ private: static const int a = 4; // valid static const std::string t ; // can't be initialized here ... ... }; // in a cpp file where the static variable will exist const std::string A::t = "this way it works";
Beachten Sie außerdem, dass diese Regel in C ++ 11 entfernt wurde. Jetzt können Sie (mit einem Compiler, der die Funktion bereitstellt) das, was Sie möchten, direkt in der Klassenmitgliedsdeklaration initialisieren.
quelle
double
ist kein integraler Typ.Statische Datenelemente (nur C ++)
Die Deklaration eines statischen Datenelements in der Mitgliederliste einer Klasse ist keine Definition. Sie müssen das statische Element außerhalb der Klassendeklaration im Namespace-Bereich definieren. Zum Beispiel:
class X { public: static int i; }; int X::i = 0; // definition outside class declaration
Sobald Sie ein statisches Datenelement definiert haben, ist es vorhanden, obwohl keine Objekte der Klasse des statischen Datenelements vorhanden sind. Im obigen Beispiel sind keine Objekte der Klasse X vorhanden, obwohl das statische Datenelement X :: i definiert wurde.
Statische Datenelemente einer Klasse im Namespace-Bereich sind extern verknüpft. Der Initialisierer für ein statisches Datenelement befindet sich im Bereich der Klasse, die das Element deklariert.
Ein statisches Datenelement kann von einem beliebigen Typ sein, mit Ausnahme von void oder void, die mit const oder volatile qualifiziert sind. Sie können ein statisches Datenelement nicht als veränderbar deklarieren.
Sie können nur eine Definition eines statischen Elements in einem Programm haben. Unbenannte Klassen, Klassen in unbenannten Klassen und lokale Klassen dürfen keine statischen Datenelemente haben.
Statische Datenelemente und ihre Initialisierer können auf andere statische private und geschützte Mitglieder ihrer Klasse zugreifen. Das folgende Beispiel zeigt, wie Sie statische Elemente mit anderen statischen Elementen initialisieren können, obwohl diese Elemente privat sind:
class C { static int i; static int j; static int k; static int l; static int m; static int n; static int p; static int q; static int r; static int s; static int f() { return 0; } int a; public: C() { a = 0; } }; C c; int C::i = C::f(); // initialize with static member function int C::j = C::i; // initialize with another static data member int C::k = c.f(); // initialize with member function from an object int C::l = c.j; // initialize with data member from an object int C::s = c.a; // initialize with nonstatic data member int C::r = 1; // initialize with a constant value class Y : private C {} y; int C::m = Y::f(); int C::n = Y::r; int C::p = y.r; // error int C::q = y.f(); // error
Die Initialisierungen von C :: p und C :: q verursachen Fehler, da y ein Objekt einer Klasse ist, die privat von C abgeleitet ist und deren Mitglieder Mitgliedern von C nicht zugänglich sind.
Wenn ein statisches Datenelement vom Typ const-Integral oder const-Aufzählung ist, können Sie in der Deklaration des statischen Datenelements einen konstanten Initialisierer angeben. Dieser konstante Initialisierer muss ein integraler konstanter Ausdruck sein. Beachten Sie, dass der Konstanteninitialisierer keine Definition ist. Sie müssen das statische Element weiterhin in einem umschließenden Namespace definieren. Das folgende Beispiel zeigt dies:
#include <iostream> using namespace std; struct X { static const int a = 76; }; const int X::a; int main() { cout << X::a << endl; }
Die Token = 76 am Ende der Deklaration des statischen Datenelements a sind ein konstanter Initialisierer.
quelle
Der Vollständigkeit halber füge ich die statischen Vorlagenelementvariablen hinzu.
template<class T> struct X{ static T x; }; template<class T> T X<T>::x = T(); int main(){ X<int> x; }
quelle
Sie können statische Elemente in Konstruktoren nicht initialisieren. Integrale Typen können Sie bei ihrer Deklaration inline initialisieren. Andere statische Elemente müssen (in einer
.cpp
) Datei definiert sein:// .h class A{ private: static const int a = 4; static const foo bar; ... ... }; // .cpp const foo A::bar = ...;
quelle