Objekt ohne new instanziieren ?



  • Hi Leute,

    ich hab mal ne kleine Frage zum instanziieren von Objekten in Cpp.

    angenommen ich hab eine Klasse "Auto" dann kann ich ja das Objekt ganz normal so instanziieren:

    Variante 1

    Auto myCar("BMW");
    

    oder ich kann es mittels Pointer instanziieren, Variante 2

    Auto* myCar = new Auto("BMW");
    

    meine Frage ist jetzt wo genau der unteschied ist.
    Klar das eine ist ein Pointer auf "myCar" und den kann ich im Pgm nutzen bis ich ihn wieder lösche und der andere wird automatisch gelöscht wenn der scope dieser variablen zu ende ist oder?

    Ich weiß jetzt nicht so richtig ob ich das richtig verstanden habe.

    Vielleicht kann mir auch nochmal einer Sagen welches von den zwei Objekten jetzt auf dem Stack und welches auf dem Heap liegt.

    Hoffe ihr könnt mir helfen.

    thx, mfg byte



  • sagwen wir mal, ein Auto belegt 100 Bytes.

    Auto myCar("BMW");
    Compiler legt 100 Bytes auf dem Stack an und ruft dann den Konstruktor auf, dem er die Adresse des Anfangs des neuen Speichers übergibt.

    Auto* myCar;
    Compiler legt 4 Bytes auf dem Stack an
    myCar = new Auto("BMW");
    Compiler legt 100 Bytes auf dem Freispeicher an und ruft dann den Konstruktor auf, dem er die Adresse des Anfangs des neuen Speichers übergibt. Diese Adresse ist auch der Rückgabewert von new und wird in die 4 bytes auf dem Stack kopiert.



  • ahso ok
    also im ersten fall sind auch alle einfachen Datentypen der Klasse Auto (z.B. der String "name") auf dem Stack, im zweiten Fall ist nur die Adresse auf dem Stack die auf den Heap verweißt aber die einfachen Datentypen meiner Klasse sind auf dem Heap richtig?

    mfg byte



  • Genau so ist das! Es sind allerdings nicht zwangsläufig 4 Byte die auf dem Stack reserviert werden. Auf 64 Bit Platformen belegen Zeiger imho 8 Byte.



  • Hmm also ich kann in Cpp Instanzen einer Klasse auf den Stack ablegen?
    In Java geht das nicht oder bzw. kenn ich es aus Java nur so das eine Instanz IMMER auf dem Heap liegt.
    Aber hier sieht es für mich so aus als ob hier ein Unterschied zwischen Cpp und Java vorliegt oder?

    Sorry das ich soviel frage 😃
    Bin Cpp-Anfänger und hab bis jetzt nur Java gemacht, Problem ist das man in Java nie so richtig "Speicherverwaltung" machen muss und ich deshalb nicht soviel Ahnung davon habe

    mfg byte



  • Das ist nicht der einzige Unterschied! 😉 Aber ja, du kannst in C++ wählen wo du deine Objekte ablegenwillst. Bedenken musst du natürlich das dein Stack nur sehr begrenzt ist.

    grüße



  • Grosse Objekte solltest du generell auf dem Freispeicher reservieren, da, wie David schon sagte, der Stack begrenzt ist. Man kann ihn gewöhnlich anpassen, ist aber selten wirklich notwendig. Zudem ist dynamische Reservierung dann notwendig, wenn du ein Objekt über den aktuellen Gültigkeitsbereich hinaus benötigst.
    Ansonsten solltest du grundsätzlich die Stack Instanzierung verwenden, weil
    - das Reservieren des Speichers erheblich schneller erfolgt
    - du dich nicht um die Feigabe des Speichers kümmern musst und somit keine Speicherlecks entstehen
    - kein zusätzlicher Zeiger benötigt wird (auch wenn's bei heutigen Systemen keine wirkliche Rolle spielt)



  • Zudem ist dynamische Reservierung dann notwendig, wenn du ein Objekt über den aktuellen Gültigkeitsbereich hinaus benötigst.

    Dazu hab ich auch noch eine Frage.

    Heißt das, dass eigentlich sowas gehen müsste:

    int main()
    {
        {
        Auto* a = new Auto;
        }
    
    a->drive();
    delete a;
    }
    

    Jedenfalls klappt das bei mir nicht:

    "auto undeclared (first use this function)"

    😕

    Wäre dankbar, wenn mir das jemand erklären könnte.



  • Nein das geht so nicht, weil a halt nur in dem Block definiert ist. Eher sollte das so gehen:

    int main()
    {
    Auto* b;
        {
        Auto* a = new Auto;
        b = a;
        }
    
    b->drive();
    delete b;
    }
    


  • sly schrieb:

    Zudem ist dynamische Reservierung dann notwendig, wenn du ein Objekt über den aktuellen Gültigkeitsbereich hinaus benötigst.

    Dazu hab ich auch noch eine Frage.

    Heißt das, dass eigentlich sowas gehen müsste:

    int main()
    {
        {
        Auto* a = new Auto;
        }
    
    a->drive();
    delete a;
    }
    

    Jedenfalls klappt das bei mir nicht:

    "auto undeclared (first use this function)"

    😕

    Wäre dankbar, wenn mir das jemand erklären könnte.

    Vll. liegts daran das du keine Klasse mit dem Namen Auto hast? 🙄
    Ansonsten kann ich 🙂 zustimmen 🙂



  • Das liegt allerdings nicht an der Fehlenden Klasse... 🙂 hat das Problem schon gut beschrieben! 😉

    grüße



  • Vll. liegts daran das du keine Klasse mit dem Namen Auto hast? 🙄

    Ich hatte mich verschrieben. Ich meinte "a not declared..."

    🙂 schrieb:

    Nein das geht so nicht, weil a halt nur in dem Block definiert ist. Eher sollte das so gehen:

    int main()
    {
    Auto* b;
        {
        Auto* a = new Auto;
        b = a;
        }
    
    b->drive();
    delete b;
    }
    

    bzw. so?

    int main()
    {
    Auto* b;
        {
        b = new Auto;
        }
    
    b->drive();
    delete b;
    }
    


  • jop das müsste gehenb weil du "b" auserhalb des scopes deklariert hast. lieg ich da richtig?

    mfg byte



  • sly schrieb:

    ...

    int main()
    {
        {
        Auto* a = new Auto;
        }
    
    a->drive();
    delete a;
    }
    

    "a undeclared (first use this function)"

    😕

    Wäre dankbar, wenn mir das jemand erklären könnte.

    Das liegt einfach daran, dass der Zeiger a außerhalb des inneren Scopes nicht mehr bekannt ist. Dein "Auto" ist schon noch da ... Du weißt nur nicht mehr, wo 😉

    Gruß,

    Simon2.


Anmelden zum Antworten