Funktion gibt objekt zurück



  • Meine Frage betrifft folgenden Code:

    class testclasse
    {
    public:
    int i;
    ~testclasse()
    {
    cout<<"Destruktor";
    }

    }

    testclasse TestFunktion()
    {
    testclasse t1(1);
    return t1
    }

    Wenn ich die TestFunktion aufrufe, sollte doch ein testclasse-objekt auf dem Stack erzeugt und bei der Rückkehr wieder zerstört werden. Ich dachte also, dass der Destruktor aufgerufen wird.
    Dies passiert jedoch erst, wenn das Programm vorbei ist.

    Warum ist das so?



  • verlegenheitsname schrieb:

    Meine Frage betrifft folgenden Code:

    Der compiliert nicht. Meintest du vielleicht anderen Code?

    Wenn ich die TestFunktion aufrufe, sollte doch ein testclasse-objekt auf dem Stack erzeugt und bei der Rückkehr wieder zerstört werden. Ich dachte also, dass der Destruktor aufgerufen wird.
    Dies passiert jedoch erst, wenn das Programm vorbei ist.

    Wenn das Programm vorbei ist, wird überhaupt nichts mehr aufgerufen, denn sonst wäre das Programm ja nicht vorbei?! Der Destruktor wird selbstverständlich aufgerufen.

    Wunderst du dich ggf. hierüber? https://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization

    Wenn das nicht zutrifft, poste bitte ein compilierbares Beispiel in Codetags.



  • Entschuldigung, jetzt hab ich das mit den Code-Tags verstanden.

    class test
    {
    public: 
        int i = 0;
        test()
        {        
            cout<<"Konstruktor ohne argument"<<i<<endl;
        }
        test(int k)
        {
            i=k;
            cout<<"Konstruktor mit argument"<<i<<endl;
        }
        ~test()
        {
            cout<<"Destruktor "<<i<<endl;
        }
        test(const test &p)
        {
            i = p.i;
            cout<<"kopie-konstruktor"<<i<<endl;
        }
    
    test check()
    {
        test t(344); 
        return t;
    }
    
    int main(int argc, char** argv) 
    {  
        test obj = check();
        cout<<obj.i<<endl;
    
    };
    

    Nochmals meine Frage: Warum wird der Kopier-Konstruktor nicht aufgerufen und das Objekt
    bereits in der Funktion zerstört?
    Aber, ein Danke an wob für den Link, offenbar eine Optimierungsgeschichte.



  • Genau um die Optimierungsgeschichten geht es aber in deinem Beispiel. Das Objekt muss nicht kopiert werden, sondern wird gemoved. Das Stichwort ist “Return value optimization“. Genau darum geht es in wobs Link.



  • Also ich hab mal deinen Codebsp. Ohne deinen Fehler da nach getippt, weil ich mir dein Verhalten nicht erklären konnte und bei mir ruft er ganz korrekt Kopier- und Destruktor auf.

    Mit deinem Fehler meine ich, die fehlende schließende Klammer von der Klasse plus das Semikolon dazu. Aber ich gehe mal von aus, dass in deinem Codes zu Hause dies richtig ist.



  • Easy_TK schrieb:

    Also ich hab mal deinen Codebsp. Ohne deinen Fehler da nach getippt, weil ich mir dein Verhalten nicht erklären konnte und bei mir ruft er ganz korrekt Kopier- und Destruktor auf

    Hast du den Optimizer eingeschaltet? Ist der Compiler halbwegs aktuell?



  • Ich benutze ganz normales Visual Studio 2015 und warum sollte das nicht funktionieren?

    Ob das ganze jetzt Sinn macht oder nicht, mal abgesehen. Er erstellt einr instance von seiner klasse. In der Funktion erstellt er wieder eine Instanz seiner Klasse und kopiert den Inhalt in die davor erstellte Instance.

    Beim verlassen der Funktion wieder die zweite erstellte Instance wieder gelöscht.

    Also warum sollte das nicht compilieren.



  • Mach mal im VS ein Rechtsklick auf dein Projekt und gehe bei deiner aktiven Konfiguration auf C/C++ -> Optimierung. Was steht da im Feld Optimierung? Sowas wie: Geschwindigkeit maximieren (/O2)??? Wenn ja, änder das mal auf "Deaktiviert (/Od)".

    Edit: TE und Antwort durcheinander gebracht. Aber der TE sollte trotzdem mal seine Optimierungsflags überprüfen



  • Easy_TK schrieb:

    Also warum sollte das nicht compilieren.

    Wer sagt, dass es nicht compiliert?



  • @Easy_TK
    Hast du dir den Link von "wob" durchgelesen? Das ganze ist nämlich ganz normal und nennt sich "NRVO".
    Ansonsten poste bitte ein 1:1 compilierbares Beispiel (inklusive allen #include etc.), den Output den du bekommst und ne Beschreibung worüber du dich in diesem wunderst.



  • Also ich glaub hier wird gerade irgendwas verwechselt.

    Ich hab mir den Link durch gelesen und das stimmt ja auch alles und ist schön. Nur hat das der Threadersteller doch gar nicht gefragt.

    Ich hab lediglich auf seine Frage geantwortet in dem ich >>SEIN<< Code bei mir ausprobiert hab.

    Er hat sich gefragt warum bei ihm nicht der Kopierkonstruktor oder Destruktor aufgerufen wird, und über das Verhalten bei >>IHM<< habe ich mich gewundert,
    weil bei mir diese beiden in >>SEINEM<< Beispiel aufgerufen werden.

    Über das was bei mir passiert wundere ich mich nicht und ich bin mir auch im klaren was hier passiert. Ich hab aber auch keine einzige Frage gestellt, abgesehen warum es nicht compilieren sollte, weil es ja das tut und die ersten Antworten verlauten ließen, dass sie das Beispiel nicht compilieren konnten.

    Drück ich mich so umständlich aus oder wo liegt die krux?


  • Mod

    Easy_TK schrieb:

    Über das was bei mir passiert wundere ich mich nicht und ich bin mir auch im klaren was hier passiert. Ich hab aber auch keine einzige Frage gestellt, abgesehen warum es nicht compilieren sollte, weil es ja das tut und die ersten Antworten verlauten ließen, dass sie das Beispiel nicht compilieren konnten.

    Aber der Code vom TE kann ohne Korrekturen nicht compilieren! Da sind sowohl Syntaxfehler drin, als auch ist er unvollständig.

    Drück ich mich so umständlich aus oder wo liegt die krux?

    Ich glaube, du wurdest mit dem TE verwechselt. Ist eben schwer mit Unregistrierten. Ich hatte auch schon eine Antwort wie hustbaers halb fertig, bevor ich merkte, dass du jemand anderes bist.



  • Easy_TK schrieb:

    Er hat sich gefragt warum bei ihm nicht der Kopierkonstruktor oder Destruktor aufgerufen wird, und über das Verhalten bei >>IHM<< habe ich mich gewundert,
    weil bei mir diese beiden in >>SEINEM<< Beispiel aufgerufen werden.

    Über das was bei mir passiert wundere ich mich nicht und ich bin mir auch im klaren was hier passiert.

    ohne Optimizer schrieb:

    :\Temp>cl /EHsc x.cpp
    Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x64
    Copyright (C) Microsoft Corporation. All rights reserved.

    x.cpp
    Microsoft (R) Incremental Linker Version 14.00.24215.1
    Copyright (C) Microsoft Corporation. All rights reserved.

    /out:x.exe
    x.obj

    c:\Temp>x
    Konstruktor mit argument344
    kopie-konstruktor344
    Destruktor 344
    344
    Destruktor 344

    mit Optimizer schrieb:

    c:\Temp>cl /Ox /EHsc x.cpp
    Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x64
    Copyright (C) Microsoft Corporation. All rights reserved.

    x.cpp
    Microsoft (R) Incremental Linker Version 14.00.24215.1
    Copyright (C) Microsoft Corporation. All rights reserved.

    /out:x.exe
    x.obj

    c:\Temp>x
    Konstruktor mit argument344
    344
    Destruktor 344



  • SeppJ schrieb:

    Ich glaube, du wurdest mit dem TE verwechselt. Ist eben schwer mit Unregistrierten.

    Richtig erkannt 🙂



  • Ich werd mich zu Hause sofort registrieren ^^
    Aber gut das nun das Problem aus der Welt ist.

    Die Sache mit dem optimizer wusste ich so auch noch nicht expliziet :).


Log in to reply