Wann werden auf dem Stack erzeugte und per Referenz zurückgegebene Objekte zerstört?



  • Hallo,

    ich habe eine Verständnisfrage zu folgendem Code:

    Klasse& meineFunktion(void)
    {
        Klasse klasse ();
        return klasse;
    }
    

    dabei wird das Objekt Klasse ja auf dem Stack erzeugt und sollte ja eigentlich beim Verlassen der Funktion wieder vernichtet werden. Nur ich gebe ja nun eine Referenz von diesem Objekt zurück. Wo wird der Objekt angelegt, und wann wird es wieder zerstört?
    Ich weiss leider nicht unter welchem Begriff man dazu am besten googlen kann. Vielleicht kann mir jemand ein Stichwort nennen?



  • Also zu 100% bin ich mir da nicht sicher weil ich sowas nicht versuchen würde, aber ich denke mal das Objekt wird zerstört sobald Du die Methode verlässt (das ist völlig unabhängig davon ob etwas zurückgegeben wird).



  • Na, deine Funktion strotzt nur vor Fehlern!

    1. Klasse klasse (); wird dir der Compiler einen Error melden! Wenn dann Klasse klasse; .

    2. Du erzeugst eine lokale Variable und gibst sie per Referenz zurück. Da wird dir jeder gute Compiler ein Warning schmeißen! Weil das Objekt beim Verlassen zerstört wird, aber du es trotzdem zurück gibst. Crazy!

    Wenn dann versuche eine Kopie zurück zu geben:

    Klasse meineFunktion(void)
    {
        Klasse klasse;
        return klasse;
    }
    


  • Sowas lässt sich mit ein bisschen Code leicht testen:

    class Klasse
    {
    private:
    	std::string name;
    
    public:
    
    	Klasse( std::string n ) //ctor
    		: name( n )
    	{ std::cout << "ctor\n" << name << "\n"; }
    
    	Klasse(const Klasse& p) //copy ctor
    	{ std::cout << "c_ctor\n" << name << "\n"; }
    
    	~Klasse()
    	{ std::cout << "dtor\n" << name << "\n"; }
    };
    
    Klasse& meineFunktion(void)
    {
    	Klasse klasse("funktion");
    
    	return klasse;
    }
    
    int main(int argc, char* argv[])
    {
    	std::cout << "test1\n";
    
    	meineFunktion();
    
    	std::cout << "\ntest2\n";
    
    	Klasse k1 = meineFunktion();
    
    	std::cout << "\ntest3\n";
    
    	Klasse k2( meineFunktion() );
    
    	getch();
    
    	return 0;
    }
    

    erzeugt folgende Ausgabe:

    test1
    ctor
    funktion
    dtor
    funktion
    
    test2
    ctor
    funktion
    dtor
    funktion
    c_ctor
    
    test3
    ctor
    funktion
    dtor
    funktion
    c_ctor
    

    Wie du in test2 und test3 sehen kannst wird das in der Funktion erzeugte Objekt zerstört bevor der Copy-Konstruktor aufgerufen wird.
    Also wird ein Kopie von einem nicht mehr existierenden Objekt erzeugt => schlecht.

    Wenn eine Klasse nur PODs enthält kann es ab und zu sogar sein dass das Copy dir nicht wie blöd Exceptions um die Ohren haut, verlassen kannst du dich aber nicht drauf.



  • vielen Dank rean. Auf ein Stück Code zum testen hätte ich auch selbst kommen können.


Anmelden zum Antworten