@@ -5,16 +5,11 @@ points: 10 Punkte
55title : " Blatt 07: C++"
66---
77
8- ::: center
9- ** Wir arbeiten gerade an dieser Seite ...**
10- :::
11-
12- <!--
138# Zusammenfassung
149
1510Ziel dieses Aufgabenblattes ist die praktische Anwendung Ihrer C++-Kenntnisse,
1611insbesondere werden Sie Pointer, Referenzen und Klassen anwenden und vertiefen. Als
17- Anwendungsbeispiel werden Sie bestimmte in der C++-Welt wohlbekannte Smartpointer
12+ Anwendungsbeispiel werden Sie bestimmte in der C++-Welt wohlbekannte Smart-Pointer
1813modellieren sowie einen einfachen Ringpuffer programmieren. Sie lernen mit dem
1914* Reference Counting* nebenbei eine verbreitete Technik der * Garbage Collection*
2015kennen.
@@ -131,23 +126,23 @@ ist. Ein Aspekt dabei ist, dass man häufig die Freigabe der Objekte vergisst od
131126dass die Programmpfade so unübersichtlich sind, dass man nicht genau weiss, ob und
132127wann man Objekte freigeben soll (denken Sie an Exceptions).
133128
134- ## Smartpointer als Lösung
129+ ## Smart-Pointer als Lösung
135130
136131Während man in Sprachen wie Java die Speicherverwaltung komplett dem Compiler
137132überlässt oder wie in Rust mit strikten Ownership-Modellen arbeitet, hat man in C++
138133die sogenannten
139- [Smartpointer ](https://en.cppreference.com/book/intro/smart_pointers) erdacht. Diese
140- ersetzen den direkten Umgang mit den einfachen Pointern (auch als *raw pointer*
141- bezeichnet) und lösen das Problem der Freigabe der verwalteten Ressourcen.[^2] Es
142- gibt verschiedene Modelle, insbesondere gibt es die Variante *unique pointer*, bei
143- der immer nur genau ein Smartpointer gleichzeitig eine bestimmte Ressource besitzen
144- darf, und die *shared pointer*, bei der mehrere Smartpointer gleichzeitig die selbe
145- Ressource verwalten können. Sobald die Lebensdauer des *unique pointer* oder des
146- letzten *shared pointer* endet, wird die verwaltete Ressource automatisch vom
147- Smartpointer freigegeben.
134+ [ Smart-Pointer ] ( https://en.cppreference.com/book/intro/smart_pointers ) erdacht.
135+ Diese ersetzen den direkten Umgang mit den einfachen Pointern (auch als * raw
136+ pointer * bezeichnet) und lösen das Problem der Freigabe der verwalteten
137+ Ressourcen. [ ^ 2 ] Es gibt verschiedene Modelle, insbesondere gibt es die Variante
138+ * unique pointer * , bei der immer nur genau ein Smart-Pointer gleichzeitig eine
139+ bestimmte Ressource besitzen darf, und die * shared pointer* , bei der mehrere
140+ Smart-Pointer gleichzeitig die selbe Ressource verwalten können. Sobald die
141+ Lebensdauer des * unique pointer * oder des letzten * shared pointer* endet, wird die
142+ verwaltete Ressource automatisch vom Smart-Pointer freigegeben.
148143
149144Das folgende Beispiel arbeitet mit einer selbst implementierten Variante der * shared
150- pointers*. Dabei ist die Klasse `SmartToken` ein Smartpointer für Objekte vom Typ
145+ pointers* . Dabei ist die Klasse ` SmartToken ` ein Smart-Pointer für Objekte vom Typ
151146` Token ` :
152147
153148``` cpp
@@ -174,63 +169,64 @@ void fluppie() {
174169```
175170
176171Im Beispiel wird mit ` new Token("wuppie", 1, 4) ` ein neues Token-Objekt auf dem Heap
177- angelegt. Der Smartpointer `wuppie` übernimmt die Ressource im Konstruktor und
172+ angelegt. Der Smart-Pointer ` wuppie ` übernimmt die Ressource im Konstruktor und
178173verwaltet den Pointer. Wichtig ist zu beobachten: Das Token wird auf dem Heap
179- angelegt, während der Smartpointer `wuppie` eine normale lokale ("automatische")
174+ angelegt, während der Smart-Pointer ` wuppie ` eine normale lokale ("automatische")
180175Variable ist und auf dem Stack liegt.
181176
182- In der Kontrollstruktur werden weitere Smartpointer angelegt. Die ersten beiden
177+ In der Kontrollstruktur werden weitere Smart-Pointer angelegt. Die ersten beiden
183178(` fluppie ` , ` fluppie2 ` ) teilen sich die Ressource (den Pointer auf das Token) mit
184- `wuppie`. Es wird kein neues Token angelegt oder kopiert. Der dritte Smartpointer
179+ ` wuppie ` . Es wird kein neues Token angelegt oder kopiert. Der dritte Smart-Pointer
185180` foo ` verwaltet ein weiteres Token.
186181
187182Mit der Kontrollstruktur endet auch die Lebensdauer der lokalen Variablen ` fluppie ` ,
188183` fluppie2 ` und ` foo ` , sie werden automatisch vom Stack entfernt. Da ` foo ` der letzte
189- Smartpointer ist, der das Token "foo" verwaltet, wird hier die Ressource
190- freigegeben. Bei `fluppie` und `fluppie2` werden nur die Smartpointer auf dem Stack
184+ Smart-Pointer ist, der das Token "foo" verwaltet, wird hier die Ressource
185+ freigegeben. Bei ` fluppie ` und ` fluppie2 ` werden nur die Smart-Pointer auf dem Stack
191186entfernt, die verwaltete Ressource (Token "wuppie") bleibt erhalten, da die noch von
192- einem anderen Smartpointer verwaltet wird.
187+ einem anderen Smart-Pointer verwaltet wird.
193188
194- Mit dem Ende der Funktion endet auch die Lebensdauer des Smartpointers `wuppie`. Er
195- wird automatisch vom Stack entfernt, und da er im Beispiel der letzte Smartpointer
189+ Mit dem Ende der Funktion endet auch die Lebensdauer des Smart-Pointers ` wuppie ` . Er
190+ wird automatisch vom Stack entfernt, und da er im Beispiel der letzte Smart-Pointer
196191ist, der das Token "wuppie" verwaltet, wird dabei automatisch der Pointer zu
197192"wuppie" wieder freigegeben.
198193
199- Ein Smartpointer soll entsprechend folgende Eigenschaften haben:
194+ Ein Smart-Pointer soll entsprechend folgende Eigenschaften haben:
200195
201196- Verwendung soll analog zu normalen Pointern sein (Operatoren ` * ` und ` -> `
202197 überladen)
203- - Smartpointer haben niemals einen undefinierten Wert: entweder sie zeigen auf ein
204- Objekt oder auf `nullptr`[^3]
205- - Kopieren von (*shared*) Smartpointern führt dazu, dass sich mehrere Smartpointer
206- das verwiesene Objekt *teilen*
207- - Smartpointer löschen sich selbst (und das verwiesene Objekt, falls kein anderer
208- Smartpointer mehr darauf zeigt), wenn die Smartpointer ungültig werden (bei
198+ - Smart-Pointer haben niemals einen undefinierten Wert: entweder sie zeigen auf
199+ ein Objekt oder auf ` nullptr ` [ ^ 3 ]
200+ - Kopieren von (* shared* ) Smart-Pointern führt dazu, dass sich mehrere
201+ Smart-Pointer das verwiesene Objekt * teilen*
202+ - Smart-Pointer löschen sich selbst (und das verwiesene Objekt, falls kein anderer
203+ Smart-Pointer mehr darauf zeigt), wenn die Smart-Pointer ungültig werden (bei
209204 Verlassen des Scopes bzw. bei explizitem Aufruf von ` delete ` auf einen Pointer
210- auf einen Smartpointer)
211- - Es gibt keine verwitweten Objekte mehr: Wenn mehrere Smartpointer auf das selbe
212- Objekt zeigen, darf erst der letzte Smartpointer das Objekt aus dem Heap löschen
213- - Smartpointer funktionieren nur für mit `new` erzeugte Objekte
205+ auf einen Smart-Pointer)
206+ - Es gibt keine verwitweten Objekte mehr: Wenn mehrere Smart-Pointer auf das selbe
207+ Objekt zeigen, darf erst der letzte Smart-Pointer das Objekt aus dem Heap
208+ löschen
209+ - Smart-Pointer funktionieren nur für mit ` new ` erzeugte Objekte
214210
215211Weitere übliche Eigenschaften, die wir auf diesem Blatt aber vereinfachend
216212ignorieren[ ^ 4 ] :
217213
218- - Smartpointer sollen für beliebige Klassen nutzbar sein (Template-Klasse)
219- - Dereferenzierung von nicht existierenden Objekten (d.h. der Smartpointer zeigt
214+ - Smart-Pointer sollen für beliebige Klassen nutzbar sein (Template-Klasse)
215+ - Dereferenzierung von nicht existierenden Objekten (d.h. der Smart-Pointer zeigt
220216 intern auf ` nullptr ` ) führt nicht zum Programmabsturz, sondern zu einer
221217 Exception
222218
223219## Reference Counting
224220
225- Smartpointer werden erzeugt, indem sie entweder einen Pointer auf die zu verwaltende
226- Ressource bekommen (Konstruktor) oder eine Referenz auf ein anderes
227- Smartpointer -Objekt (Copy-Konstruktor).
221+ Smart-Pointer werden erzeugt, indem sie entweder einen Pointer auf die zu
222+ verwaltende Ressource bekommen (Konstruktor) oder eine Referenz auf ein anderes
223+ Smart-Pointer -Objekt (Copy-Konstruktor).
228224
229- Im Smartpointer wird entsprechend der Pointer auf die zu verwaltende Ressource
225+ Im Smart-Pointer wird entsprechend der Pointer auf die zu verwaltende Ressource
230226gespeichert.
231227
232- Für die Bestimmung, wie viele Smartpointer sich eine Ressource teilen, muss ein
233- Zähler implementiert werden. Sobald sich ein weiterer Smartpointer die selbe
228+ Für die Bestimmung, wie viele Smart-Pointer sich eine Ressource teilen, muss ein
229+ Zähler implementiert werden. Sobald sich ein weiterer Smart-Pointer die selbe
234230Ressource teilt, muss dort auch der Zähler (per Pointer!) übernommen werden und
235231entsprechend inkrementiert werden. Im Destruktor muss der Zähler dekrementiert
236232werden. Falls dabei der Zähler den Wert 0 erreicht, werden die Pointer auf die
@@ -317,13 +313,13 @@ private:
317313};
318314```
319315
320- ## Dereferenzierung von Smartpointern
316+ ## Dereferenzierung von Smart-Pointern
321317
322318(*Anmerkung*: Dies ist ein Vorgriff auf die Lektion "Operatoren". Betrachten und
323319implementieren Sie die vorgegebenen Operatoren einfach wie normale Methoden.)
324320
325321Pointer lassen sich dereferenzieren, d.h. man greift direkt auf das verwiesene
326- Objekt zu. Dies lässt sich auch für Smartpointer erreichen, indem die beiden
322+ Objekt zu. Dies lässt sich auch für Smart-Pointer erreichen, indem die beiden
327323Dereferenzierungsoperatoren überladen werden.
328324
329325``` cpp
@@ -346,7 +342,7 @@ public:
346342```
347343
348344Damit lässt sich das folgende Verhalten realisieren (Vergleich * raw* Pointer
349- vs. Smartpointer ):
345+ vs. Smart-Pointer ):
350346
351347``` cpp
352348Token* foo = new Token(" foo" , 9 , 35 ); // raw pointer foo
@@ -423,9 +419,9 @@ hier können Sie bei Bedarf zusätzliche Attribute und Methoden hinzufügen.
423419
424420Testen Sie Ihre `RefCounter`-Klasse an selbst gewählten Beispielen.
425421
426- ## A7.4: Smartpointer (3P)
422+ ## A7.4: Smart-Pointer (3P)
427423
428- Implementieren Sie nun die Smartpointer für `Token`-Objekte mit folgender Signatur
424+ Implementieren Sie nun die Smart-Pointer für `Token`-Objekte mit folgender Signatur
429425(wie oben, leicht erweitert):
430426
431427``` cpp
@@ -518,10 +514,10 @@ Attribut `head` merkt man sich stattdessen, wo das nächste zu lesende Element l
518514gewordenen Platz im internen Array `elems` eingefügt.
519515
520516Unser Ringpuffer ist auf Elemente vom Typ `SmartToken` festgelegt. Es wird davon
521- ausgegangen, dass diese Elemente Smartpointer mit der *shared pointer*-Semantik
517+ ausgegangen, dass diese Elemente Smart-Pointer mit der *shared pointer*-Semantik
522518sind.[^5 ] Da die `SmartToken` selbst (zum Teil) eine Pointersemantik implementiert
523- haben (man kann die Smartpointer dereferenzieren), vermeiden wir Pointer auf die
524- Smartpointer in der Schnittstelle und arbeiten stattdessen mit C++-Referenzen bzw.
519+ haben (man kann die Smart-Pointer dereferenzieren), vermeiden wir Pointer auf die
520+ Smart-Pointer in der Schnittstelle und arbeiten stattdessen mit C++-Referenzen bzw.
525521Kopien: Bei ` writeBuffer() ` wird ein ` SmartToken ` per konstanter C++-Referenz
526522übergeben, und bei ` readBuffer() ` wird eine Kopie des gelesenen ` SmartToken `
527523zurückgeliefert.
@@ -590,8 +586,8 @@ Bei Bedarf können Sie zusätzliche Attribute und Methoden hinzufügen.
590586
591587Testen Sie Ihre `RingBuffer`-Klasse an selbst gewählten Beispielen. Überzeugen Sie
592588sich insbesondere vom korrekten Zugriff auf die Ringstruktur und prüfen Sie, ob die
593- Smartpointer wie gewünscht arbeiten. Prüfen Sie hierzu auch die `RefCounter` der
594- beteiligten Smartpointer . Welche Sonderfälle können Sie identifizieren?
589+ Smart-Pointer wie gewünscht arbeiten. Prüfen Sie hierzu auch die `RefCounter` der
590+ beteiligten Smart-Pointer . Welche Sonderfälle können Sie identifizieren?
595591
596592[^1]: Anmerkung: Man spricht trotzdem von "Freigabe" des Objekts, obwohl lediglich
597593 der Stackpointer zurückgesetzt wird und das Objekt zunächst auf dem Stack noch
@@ -611,4 +607,3 @@ beteiligten Smartpointer. Welche Sonderfälle können Sie identifizieren?
611607
612608[^5]: Wenn Sie die obigen Aufgaben richtig gelöst haben, haben Sie genau diese
613609 Semantik vorliegen.
614- -->
0 commit comments