Speicherbedarf von Klassen / statische Klassenelemente



  • hiho,

    ich hab mal ein paar merkwürdige Fragen:

    1. Wird der Speicherbedarf einer Klasse anhand der nicht-statischen Attribute festgemacht ?

    2. Warum haben statische Attribute einer Klasse keine Auswirkung auf den Speicherbedarf ?

    3. Warum ist der Speicherbedarf hiervon

    class A {};
    

    1 Byte

    und hiervon

    class A
    {
        private:
           char ac[20];
    };
    

    20 Byte und nicht 21 Byte ?

    4. Wieso wird man gezwungen ein konstantes Array als Attribut static zu definieren? Wieso ist dies bei Variablen nicht der Fall ?

    class A
    {
        private:
           static const char ac[20]; // ohne static --> Compilerfehler
    };
    

    5. Haben primitive Datentypen eigentlich auch solche Konstruktoren, den man sich so vorstellen kann wie Konstruktoren einer Klasse ?

    Danke schonmal für eure Antworten 🙂



  • 2.) Weil sie ausserhalb der Klasse gespeichert werden.
    1.) siehe 2tens
    3.) Weils 'ne eigentliche "null" Klasse ist. Objekte sind 0 Byte gross. Gegenfrage: Wie viel Speicher braucht ein Array von 20 Elementen? Welche Probleme gibt es?
    4.) Man wird nicht gezwungen, es gibt viele Moeglichkeiten. Deine Variante ist vielleicht schlecht.
    5.) Nein.

    Selber denken, Glueck verschenken! Nicht einfach wild probieren und schauen was der Compiler uebersetzt, sondern 'nen C++ Buch lesen.

    Noch ne Frage an dich: Wievel Engel passen auf einen Stecknadelkopf?



  • Dweb schrieb:

    1. Wird der Speicherbedarf einer Klasse anhand der nicht-statischen Attribute festgemacht ?

    Ja.

    Dweb schrieb:

    2. Warum haben statische Attribute einer Klasse keine Auswirkung auf den Speicherbedarf ?

    Weil sie nur einmal und nicht für jede Instanz existieren.

    Dweb schrieb:

    3. Warum ist der Speicherbedarf hiervon [...] 1 Byte und hiervon [...] 20 Byte und nicht 21 Byte ?

    Weil jedes Objekt mindestens ein Byte gross sein muss, auch eine leere Klasse. Wenn du den Speicherplatz nutzt, ist dieses Byte nicht mehr nötig.

    Dweb schrieb:

    4. Wieso wird man gezwungen ein konstantes Array als Attribut static zu definieren? Wieso ist dies bei Variablen nicht der Fall ?

    Das ist ebenfalls eine Variable. Konstante Member musst du gleich in der Konstruktor-Initialisierungsliste initialisieren.

    Dweb schrieb:

    5. Haben primitive Datentypen eigentlich auch solche Konstruktoren, den man sich so vorstellen kann wie Konstruktoren einer Klasse ?

    Nein, POD-Typen haben keine Konstruktoren. Sie stellen also gewissermassen eine reine Bit-Sammlung dar, ohne ein gekapseltes Objekt zu repräsentieren. Initialisierung, Zuweisung und Kopie erfolgen ebenfalls bitweise. Allerdings ist die Semantik und sogar die Syntax sehr ähnlich zu Klassen, es werden einfach keine Funktionen aufgerufen.



  • Gehoeren zu den PODs bei dir auch structs dazu? Die wuerde ich nicht zu den primitiven Datentypen zaehlen.



  • knivil schrieb:

    Gehoeren zu den PODs bei dir auch structs dazu? Die wuerde ich nicht zu den primitiven Datentypen zaehlen.

    Falls du mich meinst: Primitive (skalare) Datentypen und PODs werden gleich behandelt, was Konstruktoren betrifft - sie besitzen keine.



  • Aeh, ich hab mich verschrieben ich meinte: sind PODs wie structs auch primitive Datentypen (structs sind natuerlich ohne Konstruktor PODs)? Sie sehen sehr zusammengesetzt aus. Was die Konstruktoren betrifft ... sie haben keine => also Gleichbehandlung.

    Ergaenzung zu 1):
    Alles was ein Objekt ausmacht, traegt zu seiner Groesse bei. Bei virtuellen Methoden kommt auch noch ein vtable Pointer hinzu. Wie es mit Padding und Alignment aussieht, kann ich jetzt nicht sagen, was wie irgendwo im Standard erlaubt ist.

    Desweiteren solltest du dich nicht um 1-3 und 5 so sehr kuemmern. Das macht dein Kompiler.



  • knivil schrieb:

    Aeh, ich hab mich verschrieben ich meinte: sind PODs wie structs auch primitive Datentypen (structs sind natuerlich ohne Konstruktor PODs)?

    Soweit ich weiss, hat der Begriff "primitiver Datentyp" keine genau definierte Bedeutung (zum Beispiel im Gegensatz zu "skalarer Datentyp"). Meistens wird darunter aber das gleiche verstanden, nämlich eingebaute Typen wie int , void* , long double , ...

    Insofern würde ich deine Frage mit Nein beantworten.

    knivil schrieb:

    Wie es mit Padding und Alignment aussieht, kann ich jetzt nicht sagen, was wie irgendwo im Standard erlaubt ist.

    Es ist erlaubt, dass der Compiler die Klasse zusätzlich füllt, um gewisse Optimierungen zu ermöglichen. Falls es einem um den Speicherplatz geht, kann man diese aber oft unterbinden.



  • mit gezwungen meinte hier hierbei folgendes^^

    ... ich weiß, dass man etwas Konstantes mit einer Initialisierungsliste initialisieren muss

    und hab dann

    A::A() : ac("test") {}
    

    versucht, das nicht ging.

    Im Internet hab ich dann nach einer Möglichkeit geschaut und folgendes:

    const char A::ac[5]="test";
    

    wobei das Array statisch sein muss.

    Heute morgen hab ich an der FH jemanden gefragt ob es noch andere Möglichkeiten gibt ein konstantes Array zu initialisieren, aber es wurde mir auch nur diese Möglichkeit genannt.

    darum meinte ich "gezwungen" im Bezug darauf, es nur so initialisieren zu können.



  • mit gezwungen meinte hier hierbei folgendes^^

    ... ich weiß, dass man etwas Konstantes mit einer Initialisierungsliste initialisieren muss

    und hab dann

    A::A() : ac("test") {}
    

    versucht, das nicht ging.

    Im Internet hab ich dann nach einer Möglichkeit geschaut und folgendes:

    const char A::ac[20]="test";
    

    wobei das Array statisch sein muss.

    Heute morgen hab ich an der FH jemanden gefragt ob es noch andere Möglichkeiten gibt ein konstantes Array zu initialisieren, aber es wurde mir auch nur diese Möglichkeit genannt.

    darum meinte ich "gezwungen" im Bezug darauf, es nur so initialisieren zu können.



  • Man kann Member-Arrays (noch) nicht explizit initialisieren.

    Aber das ist eigentlich nie nötig - wenn du reine Arrays willst, kannst du den Wrapper std::tr1::array ( boost::array ) nehmen. Brauchst du Zeichenketten, nimmst du std::string . Für dynamische Container kannst du dir etwas aus der STL aussuchen.



  • hrr sry for double post...

    knivil schrieb:

    Desweiteren solltest du dich nicht um 1-3 und 5 so sehr kuemmern. Das macht dein Kompiler.

    Ich finde es trägt dem Verändnis bei, wenn man auch Informationen dazu bekommt, wieso das Resultat so und so ist, und einem nicht nur gesagt wird "so wird es gemacht und fertig".



  • so, dann sag ich mal noch dankö für eure Antworten @knivil und @nexus
    🙂 wieder was gelernt 🙂


Log in to reply