private static const member



  • Hallo.

    Wenn ich in meiner Klasse eine private Konstante benötige.
    Macht es dann Sinn diese als static zu kennzeichnen.

    class MyClass
    {
        private:
            inline static const std::string MyConst = "SomeText";
           // oder 
           const std::string MyConst2 = "SomeText";
    }
    

    Wenn die Variable private ist habe ich ja sowieso von aussen keinen Zugriff. Muss dann auch nicht statisch sein. Oder doch? Oder gäbe es noch andere Gründe?



  • Wenn die Konstante static ist teilen sich alle Objekte dieser Klasse die Konstante. Sie ist quasi Teil der Klasse. Wenn sie nicht static ist ist sie Bestandteile des Objekts und jedes Objekt besitzt seine eigene Konstante. Ad hoc würde ich sagen, dass es keinen Sinn macht, sie nicht static zu machen.
    Wenn du sehr viele Objekte dieser Klasse hast und mehrere non-static Konstanten wächst der Speicherverbrauch, weil für jedes Objekt eigene Konstanten erzeugt werden.



  • Macht Sinn.

    Die Initialisierung einer statischen Konstante direkt bei Deklaration funktioniert erst sein c++ 11 ( c++ 14 / c++ 17 ?)



  • Wenn du sie mit constexpr static std::string MyConstant = "SomeText"' initialisierst sollte das mit C++11 schon gehen.



  • Ja, das ist ein Unterschied. Bei einem nicht-statischen konstanten Member gibt es keinen automatischen Zuweisungsoperator der Klasse mehr, s.a. Fehlermeldung bei Ideone-Code C++14.



  • @Th69 sagte in private static const member:

    Ja, das ist ein Unterschied.

    Auf was war das bezogen?

    Also ich kann das nun so

    constexpr static std::string MyConstant = "SomeText"
    // seit c++ 11
    

    oder so

    inline static const std::string MyConst = "SomeText";
    // seit c++ 14 ?
    

    implementieren.
    Welche Variante sollte ich vorziehen? Bzw. wo sind die Unterschiede / Vorteile / Nachteile?



  • @booster sagte in private static const member:

    @Th69 sagte in private static const member:

    Ja, das ist ein Unterschied.

    Auf was war das bezogen?

    Dass es ein unterschiedliches Verhalten gibt. Non-static Konstanten gehören zum Objekt und können nicht zugewiesen werden, daher funktioniert der default-assignment-Operator nicht:

    class Test
    {
       const int myconst = 1;
    };
    
    int main()
    {
       Test t1, t2;
        t2 = t1; // Peng!
    }
    


  • Ja ok.
    Aber nochmals auf die andere Frage hinzuweisen: constexpr oder inline?



  • constexpr impliziert inline.



  • @Swordfish sagte in private static const member:

    constexpr impliziert inline

    dann anders gefragt. constexpr ja oder nein?



  • @booster Ja.



  • Die Frage sollte eher sein, ob man anstatt eines static const std::string nicht doch eher static const char* const nimmt, weil man nie so richtig weiß, ob der Compiler static const std::string entsprechend optimieren kann. Wenn das egal ist, spricht nichts gegen static const std::string.



  • @john-0 Und was wäre mit einem std::string_view? Hast du da Erfahrungen, wie gut das Compiler optimieren?



  • Ich fasse hier nochmals die Möglichkeiten zusammen.

    // 1
    const std::string MyConst = "SomeText";  // nicht statisch
    // 2
    inline static std::string MyConst = "SomeText";
    // 3
    constexpr static std::string MyConstant = "SomeText";
    // 4
    constexpr static char* MyConstant = "SomeText"; // -> Meldung von Resharper:  ISO c++ 11 does not allow conversion from string literal to 'char*'
    // 5
    constexpr static auto MyConstant = "SomeText";  // auto ist in dem Fall auch char* ( aber meckert Resharper nicht.)
    // 6
    constexpr static std::string_view MyConstant = "SomeText";
    // 7
    constexpr static auto MyConstant = "SomeText"sv; // ebenfalls string_view
    

    wann man jetzt was nimmt wäre jezt zu bewerten.



  • Ich würde zu Nummer 3 tendieren.



    1. möglich, vielleicht nicht optimal
    2. globale variable, nicht konstant
    3. std::string Konstruktor ist (noch) nicht constexpr, das geht gar nicht.
    4. Es sollte heißen: constexpr static char const*
    5. ^
    6. möglicherweise die beste option, aber nur wenn die meisten interfaces umgestiegen sind von std::string const& auf std::string_view, sonst wird bei übergabe an Funktionen ein String konstruiert.


  • @5cript sagte in private static const member:

    std::string Konstruktor ist (noch) nicht constexpr, das geht gar nicht.

    das war nur ein test und It0101ist darauf rein gefallen. 🙂
    nein war natürlich kein Test.

    Aber das constexpr wurde mir hier ja von allen Seiten wärmstens empfohlen. Und ich nenne jetzt keine Namen.



  • zu 2: hier hatte ich lediglich das static vergessen.

    inline static const std::string MyConst= "SomeText";
    

    das geht auch und ist dann wahrscheinlich aktuell die beste Lösung sollange noch keine Durchgängigleit von string_view.



  • Ohne Verwendung ist das eine ziemlich sinnlose Frage. Ich kann mit x Situationen vorstellen in denen ein string_view nix bringt. Also per default bin ich für einen char const * const.



  • also noch 2 möglichkeiten

    @Swordfish sagte in private static const member:

    char const * const

    // 8 ?
    char const * const MyConst = "SomeText";
    

    @5cript sagte in private static const member:

    1. Es sollte heißen: constexpr static char const*
    // 9 ?
    constexpr static char const* MyConstant  = "SomeText";
    

    jetzt bin ich verwirrt.


Log in to reply