Objectpointer



  • Nochmal meine 2 cents dazu:

    Ich arbeite mit fremdem Code (bspw. eine externe Lib), und bekomme von einer Methode eine Referenz zurück. Dann gehe ich davon aus, dass diese auch gültig ist - schlicht und einfach deswegen, weil ich eine Referenz nicht auf Gültigkeit überprüfen kann. Natürlich kann es vorkommen, dass da jemand Mist gebaut hat und eine ungültige Referenz liefert. Aber mit der Signatur "Ich gebe eine Referenz zurück" sagt er mit implizit, "und diese Referenz ist gültig.". Wenn ich dagegen einen Pointer bekomme, dass muss ich diesen überprüfen.

    Soweit die Regel, Abweichungen davon müssen in der Methodendokumentation stehen, bspw. "Die zurückgegebene Referenz ist ungültig, solange nicht 'ConnectToDatabase()' aufgerufen wurde."



  • daddy_felix schrieb:

    Wenn ich dagegen einen Pointer bekomme, dass muss ich diesen überprüfen.

    Das geht aber auch nur dann, wenn das ein null pointer ist, d.h. explizit gekennzeichnet wurde, dass er auf kein Objekt zeigt.



  • [Rewind] schrieb:

    daddy_felix schrieb:

    Wenn ich dagegen einen Pointer bekomme, dass muss ich diesen überprüfen.

    Das geht aber auch nur dann, wenn das ein null pointer ist, d.h. explizit gekennzeichnet wurde, dass er auf kein Objekt zeigt.

    ja, ein Pointer kann auch auf ein ungültiges Objekt zeigen. ist dann wie bei der ungültigen Referenz mies programmiert.



  • daddy_felix schrieb:

    ja, ein Pointer kann auch auf ein ungültiges Objekt zeigen. ist dann wie bei der ungültigen Referenz mies programmiert.

    Und was (Neues) wolltest du damit sagen?



  • [Rewind] schrieb:

    daddy_felix schrieb:

    ja, ein Pointer kann auch auf ein ungültiges Objekt zeigen. ist dann wie bei der ungültigen Referenz mies programmiert.

    Und was (Neues) wolltest du damit sagen?

    ich wollte einfach nur nochmal erwähnen, dass die Semantik einer Referenz aussagt "ich bin gültig", während das bei einem Pointer eben nicht so ist.

    Entschuldigung, wenn das in den bisherigen Posts bereits in dieser Form klargestellt wurde, dann habe ich das wohl übersehen.



  • nwp3 schrieb:

    Sone schrieb:

    Nach wie vor ist das hier richtig:

    std::string a = "Hello World!"; //a ist intern ein konstanter Zeiger auf einen std::string irgendwo auf dem Stack
    

    Nein, ist es nicht. In Java hättest du recht, in C++ nicht. a ist wirklich ein std::string und kein Zeiger. Ein Zeiger auf a existiert nicht, auch nicht intern. Sonst würden auch alle Variablen 4 oder 8 Bytes extra Speicher kosten.

    Wenn du auf eine Instanz zugreifen willst, dann musst du wissen wo diese im Speicher liegt. Du kannst sie nicht herzaubern. Du musst wissen wo sie liegen. Und a ist intern ein Zeiger.

    Und zum extra Speicherplatz: Du kannst überhaupt nicht prüfen, wie viel Speicherplatz eine Variable wirklich beansprucht. Du kannst nur wissen, wie viel die Instanz einer Klasse im Speicher braucht; Aber nicht, wie viel a kostet. Auf jeden Fall musst du die Adresse der Instanz irgendwo haben.


  • Mod

    Sone schrieb:

    Wenn du auf eine Instanz zugreifen willst, dann musst du wissen wo diese im Speicher liegt. Du kannst sie nicht herzaubern. Du musst wissen wo sie liegen. Und a ist intern ein Zeiger.

    Boah, Sone! Hast du mittlerweile nicht sogar schon Post vom Großadministrator bekommen? Solch einen Unsinn habe ich selbst hier im Forum noch nie gesehen. Und du weißt, dass hier so einiges kommt.



  • *popcorn*



  • Testcode:

    int main()
    {
        int a = 10;    
        int b;
    
        int & r = a;
    
        b = a;       
        b = r;    
    }
    

    Übersetzt mit VC9 ohne Optimierungen liefert folgenden ASC:

    push	ebp
    	mov	ebp, esp
    	sub	esp, 12					; 0000000cH
    
    ; 3    :     int a = 10;    
    
    	mov	DWORD PTR _a$[ebp], 10			; 0000000aH
    
    ; 4    :     int b;
    ; 5    :     
    ; 6    :     int & r = a;
    
    	lea	eax, DWORD PTR _a$[ebp]
    	mov	DWORD PTR _r$[ebp], eax
    
    ; 7    :     
    ; 8    :     b = a;       
    
    	mov	ecx, DWORD PTR _a$[ebp]
    	mov	DWORD PTR _b$[ebp], ecx
    
    ; 9    :     b = r;    
    
    	mov	edx, DWORD PTR _r$[ebp]
    	mov	eax, DWORD PTR [edx]
    	mov	DWORD PTR _b$[ebp], eax
    
    ; 10   : }
    

    Fällt Dir der Unterschied bei der Benutzung der Referenz im Gegensatz zur Benutzung der refrenzierten Variable auf, Sone?



  • Ja.



  • Und a ist intern ein Zeiger.

    Was intern wie vom Compiler wie gehandhabt wird, liegt ausserhalb vom C++ Standard. Wenn also ueber Referenzen, Objekte und Zeiger im Kontext von C++ geredet wird, dann so wie sie im Standard definiert sind. Das im Assemblercode dann eine Adresse steht (was zwangslaeufig bei nicht primitiven Datentypen passiert), ist voellig uninteressant fuer die Semantik von Objekt, Reference und Zeiger im Kontext von C++.



  • Sone schrieb:

    Wenn du auf eine Instanz zugreifen willst, dann musst du wissen wo diese im Speicher liegt. Du kannst sie nicht herzaubern. Du musst wissen wo sie liegen.

    Nö, muss ich nicht.

    extern std::string a;
    a = "hallo";
    

    Ich habe nicht die leiseste Ahnung wo a liegt (vielleicht in einer DLL oder in einem Delphi-Programm oder in einer Assemblerbibliothek oder a existiert gar nicht) und kann trotzdem drauf zugreifen. Der Linker fummelt sich das zurecht oder meckert dass es nicht geht. Dazu weist er a eine Adresse im Speicher zu, aber die steht nur kurzzeitig im Speicher des Linkers, nicht im Programm.

    Aber ich habe noch Ideen für den Sone-Pointer:

    class string ...{
    	string operator=(const string& s){ //s ist der Sone-Pointer?
    		dosomething(this); //this ist der Sone-Pointer?
    	}
    };
    

    Noch eine Preisfrage für dich: Wie viele Pointer enthält der folgende Code (es ist genau eine Antwort richtig):

    std::string strings[100];
    





    Gleiche Frage für "int i;", "int *ip;" und "int **ipp;" und Arrays davon.

    Sone schrieb:

    Und zum extra Speicherplatz: Du kannst überhaupt nicht prüfen, wie viel Speicherplatz eine Variable wirklich beansprucht. Du kannst nur wissen, wie viel die Instanz einer Klasse im Speicher braucht; Aber nicht, wie viel a kostet.

    size_t groeszeVonAImSpeicher = sizeof a;
    

    Ich kann die Größe von Variable, inklusive Pointer, Arrays und Referenzen selbst bei Structs/Unions/Classes ganz genau wissen, schon zu Compilezeit. Ich kann nicht so einfach prüfen, wie viel Speicher (Member-)Funktionen angefordert haben.



  • nwp3 schrieb:

    Noch eine Preisfrage für dich: Wie viele Pointer enthält der folgende Code (es ist genau eine Antwort richtig):

    std::string strings[100];
    





    Ich verstehe nicht, was du mit "folgender Code" meinst. Jeder der 100 std::strings hat einen internen char-Pointer (aber das ist nicht durch den Standard garantiert). Dann ist das Array intern aber definitiv ein Pointer (auch wenn wir das nicht wissen, weil der Standard es nicht definiert).

    So gesehen würde ich auf a tippen.

    P.S.: Ja, ich hab schon kapiert dass das mit dem internen Zeiger Blödsinn sein muss.


  • Mod

    Sone schrieb:

    Dann ist das Array intern aber definitiv ein Pointer (auch wenn wir das nicht wissen, weil der Standard es nicht definiert).

    Sone, dies ist das letzte Mal, dass du Scheiß verzapfen durftest. Du wurdest gewarnt und trotzdem machst du dich und indirekt auch das Forum lächerlich, wenn du hier solchen Unsinn zum besten gibst.



  • Ist das... etwa... das Ende..? der Son(n)enuntergang?



  • Sone schrieb:

    Wenn du auf eine Instanz zugreifen willst, dann musst du wissen wo diese im Speicher liegt. Du kannst sie nicht herzaubern. Du musst wissen wo sie liegen. Und a ist intern ein Zeiger.

    Glanzleistung, infinite recursion, or wat?



  • Gibt's ja nicht, noch keiner bis jetzt...?
    Dann muss ich:

    kantaki schrieb:

    cout << sizeof(t1) << " " << sizeof(t2) << endl; // prints !!!Hello World!!!
    

    prints !!!Hello World!!!?
    Glaub ich nicht 🤡


Anmelden zum Antworten