dynamische Objekte


  • Mod

    genaugenommen wird das objekt (da temporär) in diesem fallle sogar unmittelbar nach der initialisierung von a zerstört. der author meinte vermutlich eher etwas wie:

    Object a( ... );
    Object* p = &a;
    

    und dann wird das objekt am ende des blocks zerstört werden und p ungültig.



  • folgende Aussage: "new darf nicht versehentlich durch & ersetzt werden, weil sonst der Konstruktor nur ein temporäres Objekt erzeugt, dessen Speicherbereich sofort wieder freigegeben wird."

    Vielleicht macht diese Aussage bei diesem Beispiel mehr Sinn.

    Klasse * getObject() {
       Klasse obj();
       return & obj; // nix gut
    }
    
    Klasse * getObject() {
       Klasse * obj = new Klasse;
       return obj; // etwas besser
    }
    

    Den Fehler hab ich schon gemacht 🙂
    Kurt



  • ZuK schrieb:

    Vielleicht macht diese Aussage bei diesem Beispiel mehr Sinn.

    Klasse * getObject() {
       Klasse obj();
       return & obj; // nix gut
    }
    
    Klasse * getObject() {
       Klasse * obj = new Klasse;
       return obj; // etwas besser
    }
    

    Das Beispiel ist verständlich: du erzeugst innerhalb der Funktion "getObject" ein Objekt, gibst dessen Adresse zurück und vergisst dabei, dass das innerhalb der Fuktion erzeugte Objekt nach "verlassen" der Fuktion nicht mehr existiert. Der Zeiger, der die Adresse zugewiesen bekäme, würde also sonstwohin zeigen.

    camper schrieb:

    genaugenommen wird das objekt (da temporär) in diesem fallle sogar unmittelbar nach der initialisierung von a zerstört.

    Dazu muss ich aber trotzdem noch einmal nachfragen: Was meinst du mit temporär?

    Klasse* Objekt = & Klasse(...);
    

    Der Konstruktor würde hier also tatsächlich ein Objekt erzeugen

    Klasse(...)
    

    und dessen Adresse würde auch tatsächlich dem Zeiger Objekt zugewiesen? Dann würde aber unmittelbar der Destruktor aufgerufen 😕? Warum?



  • Würde mich auch interessieren, dachte immer das Objekt lebt bis zum Ende des Blockes.

    MfG SideWinder



  • SideWinder schrieb:

    Würde mich auch interessieren, dachte immer das Objekt lebt bis zum Ende des Blockes.

    Hab ich eigentlich auch gedacht. Aber wo lebt es ? ( nicht am Stack, da hats ja keinen Platz ).
    Kurt



  • camper schrieb:

    genaugenommen wird das objekt (da temporär) in diesem fallle sogar unmittelbar nach der initialisierung von a zerstört.

    Genaugenommen wird nie ein Objekt erzeugt, da die Anweisung kein gültiges C++ ist. Der Adress-Operator kann schließlich nur auf lvalues angewendet werden. Und Klasse() ist nun mal kein lvalue.

    Würde mich auch interessieren, dachte immer das Objekt lebt bis zum Ende des Blockes.

    Nö. Temporäre Objekte leben bis zum Ende der (Top-Level) Anweisung in der sie erzeugt wurden (es sei denn sie werden an eine Referenz-auf-const gebunden. In diesem Fall leben sie mindestens solange wie die Referenz). Soweit ich weiß war das in Prä-Standard-C++ anders. Dort lebten solche temporären Objekte in der Tat bis zum Ende des Scopes in dem sie erzeugt wurden.


  • Mod

    HumeSikkins schrieb:

    camper schrieb:

    genaugenommen wird das objekt (da temporär) in diesem fallle sogar unmittelbar nach der initialisierung von a zerstört.

    Genaugenommen wird nie ein Objekt erzeugt, da die Anweisung kein gültiges C++ ist. Der Adress-Operator kann schließlich nur auf lvalues angewendet werden. Und Klasse() ist nun mal kein lvalue.

    man könnte aber & geeignet überladen:

    Object* operator&() { return this; }
    

    ich war mir nicht sicher, ob die beschränkung auf lvalues auch für objekte zutrifft, da man diese über den umweg einer memberfunktion ja immer in lvalues wandeln kann.



  • camper schrieb:

    man könnte aber & geeignet überladen:

    Natürlich. Allerdings gehört das zu den Situationen der Art:
    "When you hear hoofbeats, think horses not zebras" 😉



  • Wenns jemand interessiert. Das object lebt tatsächlich am stack wird sofort wieder zerstört.

    class a {
    public:
      a()      { b = 3;}
      ~a()     { b = 7; }
      void c() { int x = 9; }
      int b;
    };
    
    int main() {
       a * pa = &a();
       pa->c();
    }
    

    g++ produziert diesen asm-code

    main:
    .LFB10:
    	pushl	%ebp
    .LCFI0:
    	movl	%esp, %ebp
    .LCFI1:
    	subl	$56, %esp
    .LCFI2:
    	andl	$-16, %esp
    	movl	$0, %eax
    	subl	%eax, %esp
    	leal	-40(%ebp), %eax
    	movl	%eax, (%esp)
    	call	_ZN1aC1Ev          // constructor von a
    	leal	-40(%ebp), %eax
    	movl	%eax, -12(%ebp)    // pa = &a;
    .L2:
    	leal	-40(%ebp), %eax
    	movl	%eax, (%esp)
    	call	_ZN1aD1Ev          // destructor von a
    	movl	-12(%ebp), %eax   
    	movl	%eax, (%esp)
    	call	_ZN1a1cEv          // pa->c();
    	movl	$0, %eax
    	leave
    	ret
    

    Wollt's nur genau wissen
    Kurt



  • Danke für eure Infos.

    Eigentlich kommt es ja auf dasselbe raus, wenn ich einfach schreibe:

    Klasse(1,2,3);
    

    Im Debug-Mode sieht man auch, dass das Objekt durch den Konstruktor erzeugt, dann aber unmittelbar wieder durch den Destruktor zerstört wird. Ich nehme an, das nennt man dann ein temporäres Objekt (die Frage danach, was ein temporäres Objekt eigentlich ist, war ein wenig untergegangen ;))


  • Mod

    Ich nehme an, das nennt man dann ein temporäres Objekt (die Frage danach, was ein temporäres Objekt eigentlich ist, war ein wenig untergegangen ;))

    salopp gesagt, jedes objekt, dass keinen eigenen namen hat und nicht durch new erzeugt wurde - für die exakte definition guckst du 12.2 im standard.



  • class Foo{...};
    
    Foo bar(){
        return Foo();//temporäres objekt.
    }
    
    Foo x=Foo();//das zweite Foo ist wieder ein temporäres objekt
    

Anmelden zum Antworten