Initialisierung einer Klasse, wenn kein Konstruktor definiert wurde



  • Hallo zusammen!

    Mit aktuellen Compilern (VC Express 2005, MinGW, ...) erzeugt folgender Quelltext

    #include <iostream>
    #include <cstddef>
    using namespace std;
    
    class A {
        public:
        unsigned short us;
          // A(){};
        void* operator new(size_t size);
    
        static unsigned char meinKlassenChar;
    };
    
    unsigned char A::meinKlassenChar = 0xFF;
    
    void* A::operator new(size_t size) {
    
        unsigned char* p = ::new(unsigned char[size]);
    
    	for (unsigned int i=0 ; i < size ; ++i)
    		p[i] = meinKlassenChar;
    	--meinKlassenChar;
    
        return p;
    }
    
    int main() {
    
        A* myA1 = new A();
        A* myA2 = new A;
        A* myA3 = new A();
        A* myA4 = new A;
    
        cout <<  hex << (*myA1).us << endl;
        cout <<  (*myA2).us << endl;
        cout <<  (*myA3).us << endl;
        cout <<  (*myA4).us << endl;
    
        return 0;
    }
    

    die Ausgabe

    0
    fefe
    0
    fcfc
    

    Mit "älteren" Compilern (VC6, Watcom, ...) jedoch, sieht die Ausgabe so aus:

    ffff
    fefe
    fdfd
    fcfc
    

    Was genau passiert da bei der Initialisierung der Variablen? Wieso sind die Member von myA1 und myA3 mit 0 initialisiert? Ein eventuell implizit erzeugter Standardkonstruktor, der die Membervariablen initialisiert, würde doch wohl auch durch die Programmzeile

    A* myA2 = new A;
    

    aufgerufen?

    Wie werden die Member also initialisiert, bzw. was sagt der ISO-Standard dazu?

    Vielen Dank schon mal fürs Lesen 🙂


  • Mod

    unsigned char* p = ::new(unsigned char[size]);
    

    Lass die runden Klammern weg. Ich hab zwar keinen Compiler zur Hand, der das verweigert, es ist aber so nicht standardkonform (weil size kein konstanter Ausdruck ist).

    A ist ein POD. automatische und dynamische PODs werden nicht implizit initialisiert.

    new A()
    

    initialisiert das Objekt mit dem implizit generierten Defaultkonstruktor, der alle Member defaultkonstruiert, bzw. Skalare mit 0 intialsiert.

    bei

    new A
    

    unterbleibt die Initialisierung.

    Ältere Compiler sind ggf. weniger standardkonform.



  • Ich bin nicht sicher, aber ich würde sagen, da A ein POD ist (nur triviale Member, nicht virtuell, keine Kopieroperationen), greifen hier die Regeln zur POD-Initialisierung. Und die besagen (und da bin ich sicher), dass wenn ein POD default-initialisiert wird alle Mitglieder rekursiv default-initialisiert werden. Und das bedeutet, dass sie den Wert einer in den Zieltyp konvertierten 0 erhalten. Der Aufruf von new A ohne die Klammern enthält keine Default-Initialisierung, der mit Klammern schon.

    EDIT:
    Zu spät, aber camper war wie üblich eh wieder ausführlicher 😉



  • Vielen Dank für eure Antworten!

    Eine kurze Nachfrage hätte ich aber noch. 🙂

    Nachdem ich gestern nun auch den ISO-Standard kurz überflogen habe, war ich der Meinung, dass bei einem POD implizit überhaupt kein Defaultkonstruktor erzeugt wird. D.h. mit dem Ausdruck

    new T;
    

    erfolgt im Falle eines PODs keine Initialisierung. Und mit

    new T();
    

    würde eine "Value-Initialisierung" erfolgen, was dann auch das Nullsetzen bewirkt.

    Leider verträgt sich das nicht ganz mit campers Antwort. 😕

    Ein implizit erzeugter Standardkonstruktor würde doch von beiden Ausdrücken aufgerufen werden?

    Vorab meine Bitte um Nachsicht für die Haarspalterei. 🙂

    /edit/

    Bedeutet ein explizit bzw. implizit erzeugter Konstruktor nicht auch, dass das Objekt kein POD mehr ist?


  • Mod

    Sprachlich ganz streng genommen hast du recht, für POD-Klassen besteht allerdings kein beobachtbarer Unterschied zwischen Value-Initialisierung und Aufruf des Defaultkonstruktors.

    8.5/9
    Wenn für ein nicht-statisches Objekt kein Initialisierer angegeben wird, so wird nur für nicht-POD-Klassen (bzw. Arrays aus solchen Klassen) der Defaultkonstruktor aufgerufen, andernfalls unterbleibt jede Initialisierung, wie bei new A.



  • OK.

    Nochmal Danke!

    Gibt es den ISO-Standard irgendwo auf Deutsch, oder in einem html- oder chm-Format? Komme mit der PDF-Datei irgendwie nicht zurecht.

    Oder hast du den Abschnitt schnell übersetzt? 🙂



  • Hi,

    ich nutze immer den hier und komme damit ganz gut klar.

    AAABER: Die Schwierigkeit dabei liegt IMHO nicht in der Darstellungsform (Englisch, elektronisch/Papier, pdf/html, ....), sondern im Thema selbst.
    Der Standard ist eben KEIN Lernbuch/Tutorial, das einem die Sprache näherbringen will, sondern eine (möglichst) exakte Darstellung aller Spracheigenschaften.
    Prima zum Nachschlagen aber eher sperrig zum "Neulernen".

    Gruß,

    Simon2.

    P.S.: Ich möchte meiner Vermutung Ausdruck verleihen, dass Du mit "dem pdf" nicht den legalen (und kostenpflichtigen) Download von der ISO-Homepage meinst.
    Denn das solltest Du wissen ... 😉



  • Hallo!

    Ja, die Schierigkeit liegt in den vielen Definitionen. Vor allem, wenn man nicht so häufig damit zu tun hat. Ohne Querverlinkung wird das Lesen dann zur Tortur. Natürlich könnte man das auch im PDF-Format realisieren.

    Danke für deinen Hinweis. Ich habe nicht so häufig mit dem ISO-Standard zu tun und wusste daher auch nicht wie der vertrieben wird. Peinlich. 🙂

    Die PDF-Datei habe ich gestern über das englische Wikipedia zum Thema PODs gefunden. Sie ist in dem Artikel direkt verlinkt.

    OK, ich ziehe meine Frage hiermit zurück. :-)))

    Danke dir!

    Gruß



  • vic1986 schrieb:

    ...
    Ja, die Schierigkeit liegt in den vielen Definitionen. Vor allem, wenn man nicht so häufig damit zu tun hat. Ohne Querverlinkung wird das Lesen dann zur Tortur....

    Finde ich allerdings auch ! 😉
    Der Standard ist eher "Schwarzbrot": geht erst schwerer runter, macht aber auf Dauer fitter.
    Einiges verstehe ich inzwischen "aus dem Standard" heraus, Anderes nicht ... dafür suche ich dann wonders. Zur Not warte ich, bis camper hier etwas dazu sagt. 😃

    Gruß,

    Simon2.


Anmelden zum Antworten