Verständnisfrage zur Objekterstellung



  • Hallo,
    ich habe eine simple Frage zur Erstellung von Objekten. Und zwar sagen alle Bücher, dass man es so macht:

    [cpp]
    Klasse1 bla;
    [/cpp]
    

    bzw:

    [cpp]
    Klasse1 *blah = new Klasse1;
    [/cpp]
    

    Jetzt habe ich herausgefunden, dass auch soetwas funktioniert:

    [cpp]
    Klasse1 *blah = 0;
    [/cpp]
    

    Meine Frage ist jetzt, was genau ist der Unterschied zwischen den beiden Pointer-Varianten und was sind die Vor- und Nachteile?



  • Klasse bla; // bla ist ein Objekt vom Typ Klasse auf dem Stack
    Klasse* bla = new Klasse; // bla ist ein Zeiger auf ein Objekt vom Typ Klasse,
    // new Klasse erstellte ein Objekt vom Typ Klasse auf dem Heap
    // bla wird die Adresse vom diesem Objekt zugewiesen
    Klasse* bla = 0; // bla ist ein Zeiger, der auf kein Objekt zeigt.



  • Meine Frage ist jetzt, was genau ist der Unterschied zwischen den beiden Pointer-Varianten und was sind die Vor- und Nachteile?

    Bei der ersten Version wird ein Objekt auf dem Heap erstellt und dessen Adresse in im Zeiger gespeichert. Bei der zweiten Version wird kein Objekt auf dem Heap erstellt und der Nullzeiger wird gespeichert, mit dem du erstmal nichts anfangen kannst.

    Vor- und Nachteile gibt es demnach nicht, weil die Semantik (die Bedeutung) vollkommen unterschiedlich ist.



  • Morgen

    Klasse1 *blah = new Klasse1; // Pointer, der auf ein gültiges Objekt zeigt.
    
    Klasse1 *blah = 0; // Nullpointer --> Pointer der auf nichts zeigt...
    Klasse1 *blah = NULL; // ...das kannst du auch so schreiben.
    
    Klasse1 *blah; // uninitialisierter Pointer, der irgendwo hinzeigt, also auf etwas Ungültiges zeigt.
    

    Wenn du nocht nicht weißt, auf was dein Pointer mal zeigen soll, dann solltest/musst du ihn unbedingt mit 0 initialisieren, und nicht uninitialisiert lassen, weil dann kannst du ungültige Schreibzugriffe vermeiden, indem du auf 0 testest, und somit weißt, dass der Pointer noch auf nichts Gültiges verweist.

    int* pointer = 0;
    
    if(pointer == 0)
    {
        // darf nicht mit dem Pointer arbeiten, da er auf nichts Gültiges verweist.
    }
    else
    {
        // darf mit dem Pointer arbeiten, da er auf ein gültiges Objekt verweist.
    }
    

    lg



  • Wenn vor jeder Operation die Gültigkeit geprüft werden muss, ist das ein tendenzieller Hinweis auf schlechtes Design (gibt natürlich einige sinnvolle Fälle). Man sollte versuchen, Gültigkeit wo möglich als Invariante vorauszusetzen und Variablen möglichst früh sinnvoll zu initialisieren. Siehe auch hier.

    Abgesehen davon sind Schreibzugriffe auf uninitialisierte Zeiger sehr wohl erlaubt, aber eben nicht auf das Objekt dahinter (an das man durch Dereferenzierung gelangt).


Anmelden zum Antworten