C ++ wo statische Konstante initialisiert werden soll


129

ich habe ein klasse

class foo {
public:
   foo();
   foo( int );
private:
   static const string s;
};

Wo kann die Zeichenfolge sin der Quelldatei am besten initialisiert werden?

Antworten:


178

Ü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 iaußerhalb der Klassendefinition definieren (wie es jist), wenn sie in einem anderen Code als nur integralen konstanten Ausdrücken verwendet wird. Siehe Davids Kommentar unten für Details.


27
Ich habe upvoted, aber nach Überprüfung des Standards gibt es einen Fehler in Ihrem Code: imuss 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.
David Rodríguez - Dribeas

3
Basierend auf Ihrem Angebote von den Standards, so scheint es imüß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 ...
Squelart

@squelart Entschuldigung, wenn ich dumm klinge, aber ein anderes Beispiel für eine Anweisung als einen integralen konstanten Ausdruck wäre?
Saksham

3
@ Saksham Zum Beispiel das Aufrufen einer Funktion, z. B.: 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 */ }
squelart

@squelart Ich habe den Text so gelesen, dass die Definition angegeben werden muss, wenn das Element überhaupt verwendet wird - der Wortlaut im Standard beschränkt diese Anforderung nicht auf integrale konstante Ausdrücke.
VladLosev

12

Statische Mitglieder müssen in einer CPP-Übersetzungseinheit im Dateibereich oder im entsprechenden Namespace initialisiert werden:

const string foo::s( "my foo");

11

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;
}

8

Seit C ++ 17 gilt der Inline- Bezeichner auch für Variablen. Sie können jetzt statische Elementvariablen in der Klassendefinition definieren:

#include <string>

class foo {
public:
   foo();
   foo( int );
private:
   inline static const std::string s { "foo" };
};

1

static const int ARRAYSIZEIn 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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.