myClass myclass vs myClass* myclass



  • Ich hoffe, das hier macht ein ein wenig verständlicher:

    MyClass myclass; // Erzeugt eine Instanz auf dem Stack
    
    MyClass* myClassPtr; // Erzeugt einen Pointer auf ein Objekt vom Typ "MyClass" - noch nicht zugewiesen, zeigt also irgenwohin.
    
    myClassPtr = new MyClass; // es wird eine neue Instanz von "MyCLass" auf dem Heap erzeugt. myClassPtr zeigt auf diese Instanz.
    
    myClassPtr = &myclass; // myClassPtr zeigt nun auf die ganz oben erzeugte Instanz
    

    und der obligatorische Hinweis: "new" bitte nur in Verbindung mit Smart Pointern verwenden.



  • Es geht vermutlich im das Problem, dass fuer einen Namen mehrere Deklarationen existieren.



  • Beides erzeugt eine neue Instanz, und zwar logisch die gleiche (nicht die sellbe).

    Aber:
    Das "MyClass myclass;" hat als Speicherklasse den Typ auto. Das heisst, sie wird dort erstellt, wo es steht und beim nächsten passenden schließenden } zerstört.
    Du kannst da mal nach Lebensdauer von Objekten oder sowas googlen.
    Beispiel:

    {
        MyClass myclass;
        // ...
    } // <--- hier wird myclass zerstört = Destruktor wird aufgerufen
    
    // hier lebt myclass nicht mehr und alles ist weg davon
    

    Dein

    {
        MyClass * myclass = new MyClass;
        // ...
    }
    // hier lebt das Objekt hinter myclass noch, aber myclass selbst ist tot
    

    erzeugt auch eine neue Instanz, jedoch wird diese nicht gelöscht wenn der Gültigkeitsbereich abgelaufen ist. Das heist nach der schließenden geschweiften Klammer lebt das Objekt noch, nichts ist gelöscht, aber die Variable mit der du darauf zugreifst ist weg.


  • Mod

    daddy_felix schrieb:

    MyClass myclass; // Erzeugt eine Instanz auf dem Stack - wissen wir nicht, kommt darauf an, wo diese Deklaration steht
    
    MyClass* myClassPtr; // Erzeugt einen Pointer auf ein Objekt vom Typ "MyClass" - noch nicht zugewiesen, zeigt also irgenwohin - ditto
    

    Der gezeigte Code ist eben nicht minimal sondern unzureichend, weshalb knivil und ich auch genervt sind. FudW ist lange genug hier, um richtiges Fragestellen gelernt zu haben.



  • camper schrieb:

    Der gezeigte Code ist eben nicht minimal sondern unzureichend, weshalb knivil und ich auch genervt sind. FudW ist lange genug hier, um richtiges Fragestellen gelernt zu haben.

    Der reichte schon aus. Genau das was Skym0sh0 und daddy_felix gesagt haben wollte ich wissen. Vielen dank dafür.

    daddy_felix schrieb:

    und der obligatorische Hinweis: "new" bitte nur in Verbindung mit Smart Pointern verwenden.

    Was mach ich da schon wieder falsch. 😞 Ich glaube nicht das ich ein Smart Pointer benutze. Ich glaube wenn ich das hier sage bin ich direkt tot. xD



  • Ein Smart-Pointer kapselt Resourcen und sichert sie mit RAII ab. Dadurch wird abgesichert, dass die Resource auch wirklich freigegeben wird, egal was passiert (Exceptions o.ä.).

    Rohe Zeiger auf einen mit new alloziertes Objekt zeigen zu lassen ist recht gefährlich und daher in modernem C++ unüblich.



  • Sone schrieb:

    Ein Smart-Pointer kapselt Resourcen und sichert sie mit RAII ab. Dadurch wird abgesichert, dass die Resource auch wirklich freigegeben wird, egal was passiert (Exceptions o.ä.).

    Rohe Zeiger auf einen mit new alloziertes Objekt zeigen zu lassen ist recht gefährlich und daher in modernem C++ unüblich.

    Oh man. Ok schau ich mir mal an. Danke wieder etwas was ich extra lernen muss. 👎 😞



  • Fuchs aus dem Wald schrieb:

    Danke wieder etwas was ich extra lernen muss. 👎 😞

    falsche Einstellung. Freu dich, dass du dir dadurch keine Gedanken mehr über die richtige Verwendung von delete machen musst.



  • Fuchs aus dem Wald schrieb:

    Was mach ich da schon wieder falsch. 😞 Ich glaube nicht das ich ein Smart Pointer benutze. Ich glaube wenn ich das hier sage bin ich direkt tot. xD

    Nein falsch. Wenn du sie nicht benutzt, dann gibts Flames zum Frühstück 😉

    Das Ding ist einfach, wenn du ein Objekt per new erzeugst, dann bist du auch dafür verantwortlich, dass das Objekt erstens zerstört wird und zweitens, dass der Speicher des Objekts wieder freigegeben wird. Machst du das nicht, sondern erzeugst munter neue Objekte ist früher oder später dein Speicher ganz voll -> nicht gut.

    Und stell dir dann mal folgenden Code vor:

    int foo(int x)
    {
    	double * d = new double[1000*x + 14*x*x]; // viel Speicher, denn wollen wir wieder haben
    
    	while ( rand() )
    	{
    		std::string s = "djksgksdg"; // '
    
    		if ( s[5] == ' ' )
    			return 0; // *
    
    		double arg = d[0] * 0.1;
    		for(int i = 0; i < x; ++i)
    		{
    			d[i] = rand() / 247.0;
    			if ( d[i] == 3.141592 )
    				return 3; // *
    		}
    
    		if ( s.size() < 10 )
    			return s.size(); // *
    	}
    
    	return 100; // *
    }
    

    Macht total unsinnigen und unlogischen Müll. Aber er erzeugt ein Array per new. Folglich müssen wir dafür sorgen, dass das auch gelöscht wird per delete[]. Und zwar wo? Genau an jeder Stelle wo ein Stern als Kommentar steht:

    int foo(int x)
    {
    	double * d = new double[1000*x + 14*x*x]; // viel Speicher, denn wollen wir wieder haben
    
    	while ( rand() )
    	{
    		std::string s = "djksgksdg"; // '
    
    		if ( s[5] == ' ' )
    		{
    			delete[] d;
    			return 0;
    		}
    
    		double arg = d[0] * 0.1;
    		for(int i = 0; i < x; ++i)
    		{
    			d[i] = rand() / 247.0;
    			if ( d[i] == 3.141592 )
    			{
    				delete[] d;
    				return 3;
    			}
    		}
    
    		if ( s.size() < 10 )
    		{
    			delete[] d;
    			return s.size();
    		}
    	}
    
    	delete[] d;
    	return 100; // *
    }
    

    Schon recht unübersichtlich, nicht wahr? 😃

    Aber das reicht nicht. Was passiert denn wenn irgendwo noch eine Exception fliegt? (In dem Code durch den ' im Kommentar angegeben)

    Tja, die müssten wir dann fangen, verarbeiten und auch den Speicher freigeben. In dem Codeschnipsel ist das noch simpel, da das nur an ein oder 2 Stellen passieren kann (da ich nur Grunddatentypen verwendet habe).

    Aber wie sieht das in richtigem Code aus, der etwas größer und komplexer ist?

    Richtig, da benutzen wir modernes C++ und haben statt dem dynamsichen Array einen std::vector<double>. Oder einen std::unique_ptr oder einen std::shared_ptr oder oder.

    DAs sind automatische Zeiger, die den Speicher, auf den sie zeigen, automatisch löschen, wenn sie zerstört werden 🙂



  • daddy_felix schrieb:

    falsche Einstellung. Freu dich, dass du dir dadurch keine Gedanken mehr über die richtige Verwendung von delete machen musst.

    Muss ich ja leider doch! 😞

    Skym0sh0 schrieb:

    [
    Nein falsch. Wenn du sie nicht benutzt, dann gibts Flames zum Frühstück 😉

    Ja von euch wenn nicht. Wenn ich die benutze gibt es hier flames. 😉

    Danke für diene weitere Ausführung! Sehr hilfreich!


  • Mod

    Fuchs aus dem Wald schrieb:

    daddy_felix schrieb:

    falsche Einstellung. Freu dich, dass du dir dadurch keine Gedanken mehr über die richtige Verwendung von delete machen musst.

    Muss ich ja leider doch! 😞

    Aber nur ein einziges Mal im Leben und danach nie wieder, da du den einmal geschriebenen Smartpointer immer wieder benutzen kannst. Und da sich jemand anderes diese Gedanken bereits gemacht hat, brauchst du das sogar nicht einmal ein einziges Mal im Leben zu machen*, sondern kannst gleich die fertigen Smartpointer benutzen. Die haben dann auch an solch nicht direkt offensichtliche Dinge gedacht, wie eine Spezialisierung für Arrays.

    *Es ist aber natürlich trotzdem gut, einmal darüber nachzudenken und zu verstehen, wie die Smartpointer funktionieren.



  • SeppJ schrieb:

    Aber nur ein einziges Mal im Leben und danach nie wieder, da du den einmal geschriebenen Smartpointer immer wieder benutzen kannst. Und da sich jemand anderes diese Gedanken bereits gemacht hat, brauchst du das sogar nicht einmal ein einziges Mal im Leben zu machen*, sondern kannst gleich die fertigen Smartpointer benutzen. Die haben dann auch an solch nicht direkt offensichtliche Dinge gedacht, wie eine Spezialisierung für Arrays.

    *Es ist aber natürlich trotzdem gut, einmal darüber nachzudenken und zu verstehen, wie die Smartpointer funktionieren.

    Jo ich schau mir die jedenfalls an. Noch knapp 100 Seiten dann werden die auch in meinem Buch behandelt. (Der C++ Programmierer)

    P.S.:
    Wenn wundert das... Ich hab da jemanden im Forum gefunden. Kommt euch der kram bekannt vor?
    http://www.c-plusplus.net/forum/314084-20


Anmelden zum Antworten