524 Stimmen

Statische Konstante string (Klassenmitglied)

Ich möchte eine private statische Konstante für eine Klasse (in diesem Fall eine Form-Fabrik) haben.

Ich hätte gerne etwas in dieser Art.

class A {
   private:
      static const string RECTANGLE = "rectangle";
}

Leider erhalte ich alle Arten von Fehlern vom C++ (g++) Compiler, wie zum Beispiel:

ISO C++ verbietet die Initialisierung von Mitglied 'RECTANGLE'

Ungültige klasseninterne Initialisierung eines statischen Datenelements vom nicht integralen Typ 'std::string'

Fehler: 'RECTANGLE' wird statisch

Das sagt mir, dass diese Art von Bauteilkonstruktion nicht mit der Norm übereinstimmt. Wie kann man eine private literale Konstante (oder vielleicht public) haben, ohne eine #define-Direktive zu verwenden (ich möchte die Hässlichkeit der Datenglobalität vermeiden!)

Für jede Hilfe sind wir dankbar.

589voto

AnT Punkte 300728

Sie müssen Ihr statisches Mitglied außerhalb der Klassendefinition definieren und dort den Initialisierer bereitstellen.

Erste

// In a header file (if it is in a header file in your case)
class A {   
private:      
  static const string RECTANGLE;
};

und dann

// In one of the implementation files
const string A::RECTANGLE = "rectangle";

Die Syntax, die Sie ursprünglich verwenden wollten (Initialisierer innerhalb der Klassendefinition), ist nur bei Integral- und Enum-Typen zulässig.


Ab C++17 haben Sie eine weitere Option, die Ihrer ursprünglichen Deklaration sehr ähnlich ist: Inline-Variablen

// In a header file (if it is in a header file in your case)
class A {   
private:      
  inline static const string RECTANGLE = "rectangle";
};

Eine zusätzliche Definition ist nicht erforderlich.

Ausgehend von C++20 anstelle von const können Sie es erklären constexpr in dieser Variante. Explizit inline wäre nicht mehr notwendig, da constexpr impliziert inline .

179voto

abyss.7 Punkte 13002

In C++11 können Sie das jetzt tun:

class A {
 private:
  static constexpr const char* STRING = "some useful string constant";
};

34voto

sellibitze Punkte 26706

Innerhalb von Klassendefinitionen können Sie nur deklarieren statische Mitglieder. Sie müssen definiert außerhalb des Unterrichts. Für integrale Konstanten zur Kompilierzeit macht die Norm die Ausnahme, dass man Mitglieder "initialisieren" kann. Das ist aber immer noch keine Definition. Die Übernahme der Adresse würde zum Beispiel ohne Definition nicht funktionieren.

Ich möchte 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 gut, aber es erfordert dynamische Initialisierung. Wenn Sie also etwas schreiben wie

const std::string foo = "hello";

im Namespace-Bereich wird der Konstruktor von foo ausgeführt, bevor die Ausführung von main beginnt, und dieser Konstruktor erstellt eine Kopie der Konstante "hello" im Heap-Speicher. Wenn Sie nicht wirklich brauchen, dass RECTANGLE ein std::string ist, können Sie genauso gut schreiben

// class definition with incomplete static member could be in a header file
class A {
    static const char RECTANGLE[];
};

// this needs to be placed in a single translation unit only
const char A::RECTANGLE[] = "rectangle";

So! Keine Heap-Allokation, kein Kopieren, keine dynamische Initialisierung.

Prost, S.

22voto

Oz Solomon Punkte 2871

In C++ 17 können Sie Inline-Variablen :

class A {
 private:
  static inline const std::string my_string = "some useful string constant";
};

Beachten Sie, dass dies ein Unterschied ist zu Antwort von abyss.7 : Dieser definiert eine aktuelle std::string Objekt, nicht ein const char*

17voto

GManNickG Punkte 476445

Dies ist nur eine zusätzliche Information, aber wenn Sie die Zeichenkette wirklich in einer Header-Datei benötigen, versuchen Sie etwas wie:

class foo
{
public:
    static const std::string& RECTANGLE(void)
    {
        static const std::string str = "rectangle";

        return str;
    }
};

Ich bezweifle allerdings, dass das empfehlenswert ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X