Antworten:
Überall in einer Kompilierungseinheit (normalerweise eine CPP-Datei) ist Folgendes möglich:
foo.h
class foo {
static const string s; // Can never be initialized here.
static const char* cs; // Same with C strings.
static const int i = 3; // Integral types can be initialized here (*)...
static const int j; // ... OR in cpp.
};
foo.cpp
#include "foo.h"
const string foo::s = "foo string";
const char* foo::cs = "foo C string";
// No definition for i. (*)
const int foo::j = 4;
(*) Gemäß den Standards müssen Sie i
außerhalb der Klassendefinition definieren (wie es j
ist), wenn sie in einem anderen Code als nur integralen konstanten Ausdrücken verwendet wird. Siehe Davids Kommentar unten für Details.
i
müßte definiert werden wird nur , wenn es irgendwo anders verwendet als in integralem konstantem Ausdrücken, nicht wahr? In diesem Fall können Sie nicht sagen, dass ein Fehler vorliegt, da nicht genügend Kontext vorhanden ist, um sicherzugehen - oder genau genommen ist das obige Beispiel korrekt, wenn kein anderer Code vorhanden ist. Jetzt freue ich mich über Ihren Kommentar (+1), ich lerne immer noch selbst! Also werde ich versuchen, diesen Punkt in der Antwort zu klären, bitte lassen Sie mich wissen, ob es besser ist ...
int f() { return 42; } class foo { static const int i = f(); /* Error! */ }
Beachten Sie, dass C ++ 11 das Aufrufen von 'constexpr'-Funktionen ermöglicht:constexpr int f() { return 42; } class foo { static const int i = f(); /* Ok */ }
Statische Mitglieder müssen in einer CPP-Übersetzungseinheit im Dateibereich oder im entsprechenden Namespace initialisiert werden:
const string foo::s( "my foo");
In einer Übersetzungseinheit innerhalb desselben Namespace, normalerweise oben:
// foo.h
struct foo
{
static const std::string s;
};
// foo.cpp
const std::string foo::s = "thingadongdong"; // this is where it lives
// bar.h
namespace baz
{
struct bar
{
static const float f;
};
}
// bar.cpp
namespace baz
{
const float bar::f = 3.1415926535;
}
static const int ARRAYSIZE
In der Header-Datei werden nur ganzzahlige Werte (z. B. ) initialisiert, da sie normalerweise im Klassen-Header verwendet werden, um beispielsweise die Größe eines Arrays zu definieren. Nicht ganzzahlige Werte werden in der Implementierungsdatei initialisiert.
i
muss in der cpp definiert werden . §9.4.2 / 4 Wenn ein statisches Datenelement vom Typ const Integral oder const Enumeration ist, kann seine Deklaration in der Klassendefinition einen Konstanteninitialisierer angeben, der ein integraler konstanter Ausdruck sein soll (5.19). In diesem Fall kann das Element in ganzzahligen konstanten Ausdrücken erscheinen. Das Mitglied muss weiterhin in einem Namensraumbereich definiert sein, wenn es im Programm verwendet wird, und die Definition des Namespace-Bereichs darf keinen Initialisierer enthalten.