Referenztypen Flashcards
Betrachte folgenden Code:
ππππ ππ ππ(πππ π‘, πππ π’) { πππ π = π‘; π‘ = π’; π’ = π; }
πππ ππππ() { πππ π = πΈ; πππ π = π·; ππ ππ(π, π); ππππππ(π == π· && π == πΈ); }
Wo kommt es hier zu einem Problem und warum? Wie kann man es beheben?
Die Variablen π‘ und π’ sind nur in der Funktion definiert, jedoch nicht ausserhalb. So macht die ππ ππ-Funktion also rein gar nichts (auch wenn in der main-Function statt a und b erneut x und y verwendet werden.)
Das Programm bricht also bei der Assertion ab.
Um dies zu umgehen, macht man eine Referenz β&β zu den in der Funktion definierten Variablen, so dass das Programm weiss, auf diese Werte zugreifen zu mΓΌssen:
ππππ ππ ππ(πππ& π‘, πππ& π’) {
β¦
Sei π ein Typ (z.B. πππ). Welche zwei Dinge hat der Referenztyp π& mit π gemeinsam und welche sind anders und inwiefern?
Gleich sind Wertebereich und FunktionalitΓ€t (πππ und πππ& reprΓ€sentieren z.B. beide die ganzen Zahlen und haben den gleichen Wertebereich).
Verschieden hingegen sind Initialisierung und Zuweisung:
- Eine Referenz muss mit einem L-Wert initialisiert werden.
- Die Variable wird dabei ein Alias des L-Werts .
- Zuweisung an die Referenz erfolgt an das Objekt hinter dem Alias.
Betrachte die beiden Initialisierungen:
πππ& π;
πππ& π = π»;
Weshalb sind diese Initialisierungen ungΓΌltig?
πππ& π; geht nicht, da π das Alias von irgendetwas sein muss, so wird π also keiner Adresse zugewiesen.
Bei πππ& π = π»; ist es Γ€hnlich, da Literale (hier π») keine Adresse besitzen.
Was bedeutet βPass by Referenceβ?
Ein formales Argument wird intern mit der Adresse des Aufrufarguments (L-Wert) initialisiert und damit zu einem Alias.
Dies ist nur mΓΆglich, wenn das formale Argument einen Referenztyp hat.
Bsp.:
Sei π eine in der main-Funktion deklarierte Variable und π eine in einer anderen Funktion deklarierte Variable, so wird beim Aufrufen der Funktion π mit π initialisiert, die Funktion ΓΌber π ausgefΓΌhrt und der Endwert von π (immer noch innerhalb der Funktion) dann π zugewiesen und in die main-Funktion βzurΓΌckgeschicktβ.
Was passiert, wenn das formale Argument keinen Referenztyp hat?
Es wird mit dem Wert des Aufrufarguments (R-Wert) initialisiert und damit zu einer Kopie.
Dies wird βPass by Valueβ genannt.
Was versteht man unter βReturn by Referenceβ?
Dass der RΓΌckgabetyp einer Funktion wiederum ein Referenztyp ist, z.B.:
πππ& πππ(πππ& π) {
ππππππ ++π;
}
Der Aufruf πππ(π‘) hat fΓΌr eine πππ-Variable π‘ die selbe Semantik wie ++π‘. Der Funktionsaufruf ist folglich selbst ein L-Wert, so dass Dinge mΓΆglich sind, wie:
πππ(πππ(π‘)) oder ++(πππ(π‘)).
Welches ist die Richtlinie fΓΌr den Gebrauch von Referenzen?
Wenn man eine Referenz erzeugt, muss das Objekt, auf das sie verweist, mindestens so lange βlebenβ, wie die Referenz selbst.
Welche der folgenden Initialisierungen funktioniert und warum?
(1) πππ& π = π»;
(2) πππππ πππ& π = π»;
πππ& π = π»; funktioniert nicht, da 5 als Literal kein L-Wert ist (also keine Adresse besitzen).
πππππ πππ& π = π»; ist hingegen mΓΆglich, da Referenzen auf Konstanten mit R-Werten initialisiert werden dΓΌrfen (es wird mit der Adresse eines temporΓ€ren Objektes vom Wert des R-Wertes initialisiert).
Betrachte die folgenden drei Initialisierungen:
(1) πππππ πππ π = π»; πππ& π = π; π = πΌ;
(2) πππ π = π»; πππππ πππ& π = π; π = πΌ;
(3) πππ π = π»; πππ& π = π; π = πΌ;
Welche ist gΓΌltig und warum bzw. welche nicht und warum nicht?
(1) πππππ πππ π = π»; πππ& π = π; π = πΌ;
β¦ ist nicht gΓΌltig, da 5 als konstant deklariert ist und somit nicht von der Referenz ΓΌberschrieben werden darf.
(2) πππ π = π»; πππππ πππ& π = π; π = πΌ;
β¦ ist nicht gΓΌltig, da das Aufrufargument als konstant definiert wird und somit danach nicht mehr ΓΌberschrieben werden darf. (πππππ πππ& π ist eine βread-only-referenceβ.)
(3) πππ π = π»; πππ& π = π; π = πΌ;
β¦ ist gΓΌltig, da nichts als konstant definiert wird und somit nicht ΓΌberschrieben werden darf.
Wann sollte man ππππππ& als Argumenttyp in einer Funktion verwenden?
Die Regel lautet:
Funktionsargumenttypen, falls mΓΆglich, als ππππππ& deklarieren, da effizient und sicher.
Man verspricht so, die Aufrufargumente nachtrΓ€glich nicht mehr zu verΓ€ndern.