Statische string-Konstante (in der Klasse)
Ich würde gerne eine private statische Konstante für eine Klasse (in diesem Fall ein Form-Fabrik).
Ich würde gerne so etwas in der Art.
class A {
private:
static const string RECTANGLE = "rectangle";
}
Leider bekomme ich alle möglichen Fehler aus C++ (g++) - compiler, wie zum Beispiel:
ISO-C++ verbietet Initialisierung von
Mitglied 'RECHTECK'ungültige in-class initialization of static data member of non-integral type "std::string'
Fehler: macht 'RECHTECK' statische
Dieser sagt mir, dass diese Art von Mitglied-design ist nicht konform mit dem standard. Wie hast du ein eigenes literal-Konstante (oder vielleicht öffentlichen) ohne Verwendung einer #define-Direktive (ich möchte vermeiden, die uglyness von Daten globality!)
Jede Hilfe ist willkommen.
- Danke für all Eure tollen Antworten! Lebe SO!
- Kann mir bitte jemand sagen, was "integral" - Typ ist? Ich danke Ihnen sehr.
- Integrale Typen bezeichnet-Typen repräsentieren ganze zahlen. Siehe publib.boulder.ibm.com/infocenter/comphelp/v8v101/...
- Private static string in Ihre Fabrik ist keine gute Lösung - prüfen Sie, dass Ihr Werk die Kunden wissen, was Formen sind unterstützt, so, anstatt halten Sie es in der privaten statische, setzen Sie Sie in separaten Namensraum als static const std::string RECTANGLE = "Rechteck".
- wenn Ihre Klasse ist eine template-Klasse, dann finden Sie unter stackoverflow.com/q/3229883/52074
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie definieren Ihre statische Memberfunktion außerhalb der Klassendefinition und bieten die Initialisierung gibt.
Ersten
dann
Die syntax, die Sie ursprünglich versucht, zu verwenden (Initialisierung innerhalb der Klasse definition) nur erlaubt ist, mit integral-und enum-Typen.
Ab C++17 haben Sie eine andere option, die ganz ähnlich wie Ihre ursprüngliche Deklaration: inline-Variablen
Keine weitere definition erforderlich ist.
char const*
hat die Güte, dass es initialisiert wird, bevor alle dynamischen Initialisierung erfolgt. Damit ist in jedem Objekt, Konstruktor, können Sie sich aufRECTANGLE
worden initialisiert alreay dann.A
es ist definiert, später als Mitglied der KlasseA
.char*
oder eine statische Methode stattIn C++11 können Sie jetzt tun:
constexpr
impliziertconst
für var, nicht für Typ es Punkte. I. e.static constexpr const char* const
ist das gleiche wiestatic constexpr const char*
, aber nicht das gleiche wiestatic constexpr char*
.In Klassendefinitionen können Sie nur erklären statische Mitglieder. Sie werden definiert außerhalb der Klasse. Für compile-time-integral-Konstanten der standard stellt die Ausnahme, dass man "initialisieren" - Mitglieder. Es ist noch nicht eine definition, aber. Unter der Adresse nicht funktionieren würde, ohne definition, zum Beispiel.
Möchte ich erwähnen, dass ich nicht sehen den Vorteil der Verwendung von std::string über const char[] für Konstanten. std::string ist schön und alle, aber es erfordert dynamische Initialisierung. Also, wenn Sie so etwas schreiben
im namespace-Gültigkeitsbereich der Konstruktor von foo ausgeführt wird, die Rechte vor der Ausführung von main beginnt und dieser Konstruktor erstellt eine Kopie der Konstante "Hallo" in der heap-Speicher. Es sei denn, Sie wirklich brauchen, RECHTECK, ein std::string könnte man genauso gut schreiben
Da! Kein heap, kein kopieren, keine dynamische Initialisierung.
Cheers, s.
Dies ist nur mit zusätzlichen Informationen, aber wenn Sie wirklich wollen, dass die Zeichenfolge in eine header-Datei, versuchen Sie so etwas wie:
Obwohl ich bezweifle, dass empfohlen.
In C++ 17, die Sie verwenden können inline-Variablen:
Beachten Sie, dass dies unterscheidet sich von Abgrund.7 die Antwort: Diese definiert man eine tatsächliche
std::string
Objekt, nicht einconst char*
inline
eine Menge Duplikate ?Dies ist die Einschränkung. Also, in diesem Fall müssen Sie definieren, variable außerhalb der Klasse. finden Sie answwer von @AndreyT
Die Klasse statische Variablen können erklärt in der Kopfzeile, sondern muss definiert in einem .cpp-Datei. Dies ist, weil es kann nur eine Instanz in einer statischen variable und der compiler kann nicht entscheiden, in die generierte Objekt-Datei setzen, so dass Sie, um die Entscheidung treffen, statt.
Halten die definition einer statischen Wert mit der Deklaration in C++11
eine geschachtelte statische Struktur verwendet werden kann. In diesem Fall wird die statische member
ist eine Struktur und muss definiert werden .cpp-Datei, aber die Werte
in den header.
Anstelle der Initialisierung der einzelnen Mitglieder die gesamte statische Struktur initialisiert wird im .cpp:
Die Werte zugegriffen mit
oder -- seit die Mitglieder sind privat und sollen nur verwendet werden, von Einem -- mit
Beachten Sie, dass diese Lösung immer noch leidet unter dem problem der Bestellung von
die Initialisierung der statischen Variablen. Wenn ein statischer Wert wird verwendet, um
initialisieren Sie eine weitere statische variable, die ersten können nicht initialisiert werden
noch.
In diesem Fall die statische variable Header enthalten entweder { "" }
oder { ".h", ".hpp" }, je nach der Reihenfolge der Initialisierung erstellt der linker.
Wie erwähnt von @abyss.7 Sie können auch
constexpr
wenn der Wert der variable berechnet werden kann zur compile-Zeit. Aber wenn Sie erklären, Ihr Saiten mitstatic constexpr const char*
und Ihr Programmstd::string
sonst gibt es einen overhead, da ein neuesstd::string
- Objekt erstellt werden jedes mal, wenn Sie solch eine Konstante:Dem aktuellen standard erlaubt nur solche Initialisierung für statische Konstante Integrale Typen. So müssen Sie als AndreyT erklärt. Doch das wird sich in den nächsten standard durch die neue member-Initialisierungs-syntax.
möglich nur:
oder
constexpr
aber Sie können keine statische Funktionconst
.static const std::string RECTANGLE() const { static const std::string value("rectangle"); return value; }
Können Sie entweder für die
const char*
Lösung oben erwähnt, aber dann, wenn Sie müssen die saite die ganze Zeit, Sie gehen zu müssen, eine Menge Aufwand.Auf der anderen Seite, statische Zeichenfolge muss die dynamische Initialisierung, also, wenn Sie verwenden möchten, deren Wert während andere Globale/statische Variablen-Initialisierung, die Sie treffen könnte, das problem der Initialisierung um. Um zu vermeiden, dass die billigste Sache ist der Zugriff auf die statischen string-Objekt durch eine get-Methode, die überprüft, ob euer Objekt initialisiert wird oder nicht.
Erinnere mich nur
A::getS()
. Weil jede threading kann nur gestartetmain()
, undA_s_initialized
initialisiert wird, bevormain()
müssen Sie nicht sperren, selbst in einer Multithreading-Umgebung.A_s_initialized
ist standardmäßig " 0 " (vor der dynamischen Initialisierung), so dass, wenn Sie verwendengetS()
vor s initialisiert wird, rufen Sie die init-Funktion sicher.Btw, in der Antwort oben: "static const std::string RECTANGLE() const" statische Funktionen nicht
const
weil Sie nicht den Zustand ändern, wenn jedes Objekt sowieso (es gibt keine this-Zeiger).Schneller Vorlauf bis 2018 und C++17.
static_assert "funktioniert" zur compile-Zeit nur
};
Oben ist eine ordnungsgemäße und rechtsgültige standard-C++ - Bürger. Es kann leicht involviert und alle std:: algorithmen, Container, Dienstprogramme und eine solche. Zum Beispiel:
Genießen Sie die standard-C++ -