Konstante in Klasse als static?



  • Hallo,

    angenommen ich habe eine Konstante in einer Klasse definiert...

    class TEST {
      private:
        int i;
    
        const int std_val = 3;
    
      public:
        TEST(int _i = std_val) : i(_i) {};
    };
    

    muss ich hier die Konstante std_val als static definieren, damit sie nicht für jedes Objekt neuen Speicher belegt?



  • Hallo

    Als static würdest du sie nicht nur lokal, sondern allgemein gültig machen. Das ändert aber nichts an der Tatsache, dass der Speicher bei jeder Anlegung eines Objektes für diese statische Variable belegt wird. Nein, es ist also nicht ohne weiteres möglich.

    Mfg.
    way



  • way schrieb:

    ... dass der Speicher bei jeder Anlegung eines Objektes für diese statische Variable belegt wird. ...

    Seit wann wird denn für jedes Objekt der Speicher für static-Variablen belegt?



  • daersc schrieb:

    way schrieb:

    ... dass der Speicher bei jeder Anlegung eines Objektes für diese statische Variable belegt wird. ...

    Seit wann wird denn für jedes Objekt der Speicher für static-Variablen belegt?

    Lass ihn reden ^^
    Auf deine Frage von oben:
    "ja"

    bb



  • danke 🙂
    ich glaub dir einfach mal



  • Zoom schrieb:

    leg dir konstanten mit #define an. die brauchen keinen speicher

    ganz schlechter tip.



  • Zoom schrieb:

    leg dir konstanten mit #define an. die brauchen keinen speicher

    Warum rennen hier so viele rum, die denken, sie wüssten was...
    Ne "richtige" Konstante optimiert der Compiler eh raus - und wenn er sie nicht rausoptimieren kann, heißt das eh, dass es mit dem define schiefgegangen wäre (adresse vom define o.ä.) oder zumindest keinerlei Vorteile bringen würde...

    bb



  • Zoom schrieb:

    volkard schrieb:

    Zoom schrieb:

    leg dir konstanten mit #define an. die brauchen keinen speicher

    ganz schlechter tip.

    warum?

    weil dir jedes c++-buch davon abrät



  • Zoom schrieb:

    unskilled schrieb:

    ...und wenn er sie nicht rausoptimieren kann

    dann hast du pech. ein #define oder enum belegt nie speicher

    Ja - und ein (guter) Compiler wird JEDE Konstante (im Release-Mode) rausoptimieren...
    Es ist einfach Käse, sowas zu schreiben - mal nen C++Buch aus der Nähe gesehen?
    Dort stehen auch ab und an nen paar schöne Bsp drin, warum man es eben _nicht_ per define macht...

    bb



  • class TEST { 
      private: 
        int i; 
        static const int std_val = 3; 
      public: 
        TEST(int _i = std_val) : i(_i) {}; 
    };
    int main(){
       int std_val=3;
       cout<<std_val;
    }
    

    geht

    #define std_val 3
    class TEST { 
      private: 
        int i; 
      public: 
        TEST(int _i = std_val) : i(_i) {}; 
    };
    int main(){
       int std_val=3;
       cout<<std_val;
    }
    

    geht nicht.



  • Zoom schrieb:

    volkard schrieb:

    #define std_val 3
    ...
       int std_val=3;
    

    geht nicht.

    muss auch nicht. eine konstante ist eine konstante, wie der name schon sagt: konstant

    boar... stell dich halt noch dümmer...

    ich denke, das thema ist geklärt...



  • Zoom schrieb:

    gut sind diese beispile eigentlich nicht. im gegenteil, sogar ziemlich fragwürdig

    nungut, dass nimm dies, du bursche!

    template<typename T>
    class TEST { 
      private: 
        int i;
        static const int std_val = 4096/sizeof(T); 
        T* data;
      public: 
        TEST(int _i = std_val) : i(_i), data(new T[_i]) {
        }; 
    };
    

    - mach das mit #define
    - falls du es nicht schaffst, erkläre, warum sich jemand erst const abgewöhnen und #define angewöhnen soll, um sich dann wieder #define abgwöhnen und const angewöhnen muß, wenns zu sache geht

    typeische anwendung für solchen code sind bayerbäume, dynamische hashtables, datagrammklassen und dergleichen, wo man homogene anwendungsspezifische daten in pakete fester größe schnüren will. vermutlich ist der code also nicht fragwürdig in hinsicht auf die relevanz.


  • Administrator

    Zoom schrieb:

    volkard schrieb:

    #define std_val 3
    ...
       int std_val=3;
    

    geht nicht.

    muss auch nicht. eine konstante ist eine konstante, wie der name schon sagt: konstant

    Dir ist aber schon klar, was ein Scope ist? Denn wenn nicht, dann solltest du dringends zuerst einmal C++ anfangen zu lernen.
    Aber Konstanten per define haben viel mehr Nachteile. Das Problem ist, dass define zum Präprozessor gehört, zu einem dummen Textersetzungsding. Der Kompiler wird nie erfahren, was der Präprozessor macht. Da kann eine Konstante plötzlich zum Programmkiller werden, weil dem Präprozessor C++ Code scheiss egal ist.

    Präprozessor Anweisungen sind mit äusserster Vorsicht einzusetzen. Überall wo man sie vermeiden und auf C++ Mittel setzen kann, sollte diese vorgezogen werden. Für Konstanten gibt es in C++ das Schlüsselwort const und das sollte man auch verwenden.

    Grüssli



  • Dravere schrieb:

    Präprozessor Anweisungen sind mit äusserster Vorsicht einzusetzen. Überall wo man sie vermeiden und auf C++ Mittel setzen kann, sollte diese vorgezogen werden. Für Konstanten gibt es in C++ das Schlüsselwort const und das sollte man auch verwenden.

    Das Wort zum Sonntag 👍
    Du hast natuerlich voellig Recht. Ich versteh gar nicht, wie man darauf kommen kann, Makros als Konstantenalternative einzusetzen (schon allein wegen dem Scope).

    Ausserdem werden Konstanten wie bereits erwaehnt von guten Compilern schon bei der Kompilierung (in der Optimierung) aufgeloest, falls moeglich, sodass das Argument wegen des Speicherverbrauchs schonmal wegfaellt.

    Gruss
    Cartman



  • Zoom schrieb:

    volkard schrieb:

    - falls du es nicht schaffst, erkläre, warum sich jemand erst const abgewöhnen und #define angewöhnen soll, um sich dann wieder #define abgwöhnen und const angewöhnen muß, wenns zu sache geht

    const ist eine spezielle sache: ist im normalfall unveränderlich, kann aber durch const_cast umgangen werden. das ist nicht das, was man haben will, wenn man eine echte konstante braucht

    const double pi = 3.1415926;
    (double)pi = 999.0;  // das ist mist
    
    #define pi 3.1415926
    (double)pi = 999.0;  // compiliert nicht: richtig so!
    

    Dravere schrieb:

    Das Problem ist, dass define zum Präprozessor gehört, zu einem dummen Textersetzungsding. Der Kompiler wird nie erfahren, was der Präprozessor macht.

    warum sollte das schlecht sein?

    dein code compiliert auch nicht. oder muß es nicht. const_cast geht nur, wenn das objekt ursprünglich non-const war.

    und jetzt geh erstmal auf mein beispiel ein und sag, wie du das mit #define machen willst.


  • Administrator

    Zoom schrieb:

    warum sollte das schlecht sein?

    #define IchBinEineKonstante 5
    
    class IchBinEineKonstante
    {
    };
    
    int main()
    {
    	IchBinEineKonstante test;
    
    	return 0;
    }
    

    ... WOOOOOOPPSSSS ...

    Das ist nur ein dummes Beispiel. Aber ich ärgere mich jedes Mal zu Tode bei sowas:

    #include <windows.h>
    #include <limits>
    
    int main()
    {
      std::numeric_limits<int>::max(); // <- BUMM
    
      // Bringt sie um! Wer hatte die bescheuerte Idee statt eine Funktion zu verwenden,
      // ein Makro max zu erstellen!!!
    }
    

    Grüssli



  • ich habe ein wenig getrolle gelöscht. 😃



  • volkard schrieb:

    ich habe ein wenig getrolle gelöscht. 😃

    wie meinst du das? was habe ich falsch gemacht?



  • Meine Güte, Zoom, stelle dich nicht so an.

    Wenn du weisst, was ein Präprozessor-Makro ist und worin der Unterschied zu Compilezeit-Konstanten besteht, sollte dir bereits alles klar sein. Argumente wie " #define s brauchen keinen Speicher" sind wirklich nichts wert, wenn du einen modernen Compiler verwendest. Wie gesagt sollte allein schon der Scope Grund genug für Compilezeit-Konstanten sein. Ausserdem gibt es dafür Debugging-Symbole, man hat einen feststehenden Typen und muss nicht furchtbar aufpassen, dass die Textersetzung aufgrund fehlender Klammern oder Ähnlichem falsch durchgeführt wird.



  • Zoom schrieb:

    volkard schrieb:

    ich habe ein wenig getrolle gelöscht. 😃

    wie meinst du das?

    na, du bist uneinsichtig, gehst auf argumente nicht ein.
    und machst den eindruck, dein wissen bezüglich c++ seit den letzten 18 jahren nicht mehr aktualisiert zu haben, und weil schon damals enum{std_val=5 die bessere alternative war, es damals schon nicht beherrscht zu haben.
    also hab ich ein wenig gebremst und werde das natürlich weiter tun.


Anmelden zum Antworten