0 Daumen
1,2k Aufrufe

code.pngWie kommt man auf Obj40=Obj12 (also die 12?)  und wieso fährt der Code erst nach dem Ende je mit Abzug von 10 , beginnt das mit ab 29

Und wieso 41 und nicht 40"(Zeile 29)"

Wäre sehr nett von euch , wenn ihr mir helfen könntet

Avatar von

Vielleicht könntest du die Klasse C angeben?

class.png

sry, hab das jetzt hinzugefügt.

1 Antwort

0 Daumen

In Zeile 25 steht: "\(\text{v4 = f(v1);}\)". Diese eine(!) Zeile erzeugt die Ausgabe

$$\text{KK11}\\ \text{KK12} \\ \text{Obj40=Obj12}$$

\(\text{v1}\) ist das Objekt 10. Um es an die Funktion \(\text{f1}\) zu übergeben, muss es auf den Stack kopiert werde. Das nennt man auch Parameterübergabe per value. Dies hat das \(\text{KK11}\) in Zeile 25  zur Folge. Wenn das Objekt nun aus der Funktion \(\text{f}\) zurück gegeben wird, so muss es nochmal kopiert werden - es wird ein \(\text{KK12}\) in Zeile 16 ausgegeben. Und erst diese zweite Kopie wird dem Objekt 40 (Variable \(\text{v4}\)) zugewiesen.

Ändere mal die Zeile 15 zu \(\text{C f(const C \& x) \{}\), dann wirst Du sehen, dass die erste der beiden Kopien nicht mehr ausgeführt wird. Dies wäre eine Parameterübergabe per reference.

In Zeile 28 und 29 steht:

$$\text{C* pv6 = new C(v4)} \\ \text{delete pv6}$$

Das Objekt, auf das der Zeiger \(\text{pv6}\) zeigt, ist eine Kopie vom Objekt 40. Und daher bekommt es die Nummer 41, da im Kopier-Konstruktor \(\text{mark(c.mark+1)}\) steht - also der aktuellen Variable \(\text{mark}\) wird die nächst höhere Nummer zugewiesen. Und es wird wird auch kein temporäres (Zwischen-)Objekt auf dem Stack erzeugt, da im Kopierkonstruktor die Parameterübergabe per reference definiert ist. Anschließend wird das Objekt 41 in Zeile 29 wieder gelöscht.

Mit Ende des Programms - also nach der Ausgabe von "Ende main" - mit Erreichen des Scope-Endes in Zeile 32, werden alle Objekte auf dem Stack gelöscht. Das ist hier nur das Objekt 40. Und zwar in umgekehrter Reihenfolge, wie sie angelegt wurden (LIFO-Prinzip last in first out). Das Objekt 50 wird nicht gelöscht - das würde man als Speicherleck bezeichnen. Das ist übrigens auch ein Grund, warum man \(\text{new}\) in der Form nie in einem Applikationscode benutzen sollte!

Mit Erreichen des Programmendes - das geht über das Scope-Ende - hinaus - werden alle statisch angelegten Objekte gelöscht - also 30, 20 und 10. Wieder in umgekehrter Reihenfolge wie sie angelegt worden sind.

Avatar von

Für welche Art von Programme braucht man, dieses Kopieren(=> um 1 erweitern) der Objekte... Kannst du mir da Beispiele nennen? :)

Dieses 'Kopieren' braucht man gar nicht! Aber es ist im allgemeinen notwendig um Daten von A nach B zu bringen. Allein das inkrementieren einer Speicherzelle um 1 heißt, dass der Inhalt des Speichers in ein CPU-Register kopiert wird (1.Kopie), dann inkrementiert wird und anschließend wird der Inhalt des CPU-Registers wieder in die ursprüngliche Speicherzelle zurück kopiert (2.Kopie).

Dieses erhöhen um 1 in Deinem Beispielprogramm dient nur zur Veranschaulichung, wann diese Objekte kopiert werden. Dann wird Dir sicherlich auch der Unterschied zu Parameterübergabe per value und per reference erklärt werden.

Im Allgemeinen versucht man, unnötige Kopien zu vermeiden, da dies Performamce kostet. Neben der Übergabe per reference gibt es auch die Möglichkeit Objekte zu moven. Das kommt aber eher bei etwas fortgeschrittener Programmierung dran.

Wobei in Deinem Beispiel die Referenz mindestens genauso groß ist, wie das Objekt selbst. Hier lohnt es sich also gar nicht.

Ein anderes Problem?

Stell deine Frage

Willkommen bei der Stacklounge! Stell deine Frage einfach und kostenlos

x
Made by a lovely community