Lebensdauer eines temporären Objekts



  • Laut dem Standard, bleibt eine temporäres Objekt, das an eine Referenz gebunden wird, bestehen bis die Referenz zerstört wird, außer - das temporäre Objekt wird in der Initialisierungsliste eines Konstruktors an eine Member-Referenz gebunden oder an einen Funktionsparameter. Dann endet die Lebendsdauer des Objekts mit dem Ablauf des Konstruktors bzw. der Funktion.

    Wenn ich es richtig interpretiere, dann ist folgender Code vollkommen legal:

    const A& a = A();
    a.foo();
    //...
    

    Kann das jemand bestätigen, denn irgendwie kommt mir das suspekt vor.



  • Dieser Code läuft problemlos (no warning) durch den Compiler:

    #include <iostream>
    #include <conio.h>
    using namespace std;
    
    class A
    {
      public:
        A() {cout << "ctor" << endl;}
        ~A(){cout << "dtor" << endl;}
        void foo() const {cout << this << endl;};    
    };
    
    int main()
    {
      {
        const A& a = A();
        a.foo();
        A x;
        x.foo();
      }    
      getch();
    }
    


  • Shlo schrieb:

    Wenn ich es richtig interpretiere, dann ist folgender Code vollkommen legal:

    Interpretiere ich auch so.



  • Shlo schrieb:

    Laut dem Standard, bleibt eine temporäres Objekt, das an eine Referenz gebunden wird, bestehen bis die Referenz zerstört wird, außer - das temporäre Objekt wird in der Initialisierungsliste eines Konstruktors an eine Member-Referenz gebunden oder an einen Funktionsparameter. Dann endet die Lebendsdauer des Objekts mit dem Ablauf des Konstruktors bzw. der Funktion.

    Wenn ich es richtig interpretiere, dann ist folgender Code vollkommen legal:

    const A& a = A();
    a.foo();
    //...
    

    Dieser Code ist nicht nur legal sondern wird leicht abgewandelt auch gerne eingesetzt (z.B. in Alexandrescus ScopeGuard-Implementation oder Eric Nieblers FOREACH). Du kannst hier nämlich ein Objekt einer abgeleiteten Klasse an eine Basisklassenreferenz binden und das Objekt über diese automatisch zerstören lassen, ohne dass die Basisklasse einen virtuellen Destruktor besitzen muss.

    Wichtig: Bei der Bindung des Objekts an die Referenz verlängert sich die Lebenszeit des Objekts auf die der Referenz. Das Ganze ist aber nicht übertragbar. Die Lebenszeit kann sich also nicht nochmal verlängern.
    Sowas geht also nicht:

    const string& aua(const string& s) {return s;}
    
    int main()
    {
        const string& s = aua("Hallo"); // KAPUTT!
    }
    

    Aber das hast du ja selbst schon in deinem Beitrag geschrieben 🙂



  • z.B. in Alexandrescus ScopeGuard-Implementation oder Eric Nieblers FOREACH

    Natürlich! Wer kennt es nicht 😉



  • HumeSikkins schrieb:

    Dieser Code ist nicht nur legal sondern wird leicht abgewandelt auch gerne eingesetzt (z.B. in Alexandrescus ScopeGuard-Implementation oder Eric Nieblers FOREACH). Du kannst hier nämlich ein Objekt einer abgeleiteten Klasse an eine Basisklassenreferenz binden und das Objekt über diese automatisch zerstören lassen, ohne dass die Basisklasse einen virtuellen Destruktor besitzen muss.

    Sehr interessant, denn das wäre meine nächste Frage gewesen - Einsatzmöglichkeiten. 🙂



  • kannste das ein wenig genauer erklären, vieleicht noch mit einem beispiel?


Anmelden zum Antworten