Referenzen

Referenzen sind eine wertvolle Besonderheit von C++, die eine große Hilfe sind, um Fehler zu vermeiden. Sie fehlen in vielen anderen populären Sprachen, sind damit also ein Konzept, das für Umsteiger erst einmal ungewohnt scheint.

In C gibt es direkte Instanzen, sowie Zeiger, zum Beispiel

struct Point instanz;
struct Point * pointer;

Zeiger

Zeiger haben einen recht schlechten Ruf, aber ohne Zeiger lassen sich moderne, komplexe Programme nicht realisieren. Was Zeiger gefährlich macht ist, dass davon ausgegangen werden muss, dass an der Position, wohin sie zeigen, eine Instanz des Datensatzes liegt. pointer wird in obigem Code aber nicht initialisiert, wohin pointer zeigt, weiß damit keiner. Greift man nun auf pointer→XPosition zu, so erhält man irgendeine Zahl. Schreibt man auf die Position mit pointer→XPosition = 4, so schreibt man irgendwo eine 4 in den Speicher. Das hat in der Regel die Folge, dass das Programm abstürzt.

Ohne Zeiger müsste man aber bei jedem Funktionsaufruf den Datensatz kopieren. Bereits einfache Datenstrukturen wie Listen oder Bäume wären so bereits nicht mehr implementierbar. Programmieren ohne Zeiger sind also nicht möglich - auch nicht in Programmiersprachen, die behaupten, ohne Zeiger auszukommen.

Hinweis an die Java- und C#-Programmierer

Wann immer der Pfeil-Operator ' ' verwendet wird, muss der Schritt mit Bedacht und Vorsicht gegangen werden. Wer in C# oder Java programmiert, sollte wissen, dass der .-Operator in diesen Sprachen dem Pfeiloperator in C++ entspricht - und eben nicht dem Punktoperator von C oder C++. Java und C# kennen keine Referenzen, sondern referenzieren nur Zeiger. Es bleiben aber weiterhin Zeiger mit ihren Gefahren.

Instanzen

Instanzen haben einen großen Vorteil: Sie existieren definitiv.

struct Point instanz;

Beim Zugriff kann man also gar nicht danebengreifen.

Referenzen

Referenzen versuchen die Vorteile von Instanzen und Zeigern zu kombinieren. Eine Referenz ist ein Zeiger, der gültig initialisiert sein muss. Eine Referenz muss zwangsläufig mit einer Variable belegt werden.

Referenzen sind sogesehen die Adressen von Instanzen. Das sind Pointer auch. Ein Pointer darf aber NULL sein, bei einer Referenz ist die Betonung eher, dass zwar die Adresse der Instanz gespeichert wird, aber mit genau dieser Instanz gearbeitet werden wird. Daher wird bei einer Referenz auch nicht der Dereferenzierungsoperator (*) verwendet, sondern der Adressoperator (&). Da eigentlich nicht dereferenziert wird (in Wirklichkeit muss natürlich dereferenziert werden, da ja nur die Adresse gespeichert wird), wird bei der Verwendung auch der Punktoperator verwendet:

struct Point instanz;
struct Point * pointer = &instanz;
struct Point & referenz = instanz;
 
instanz.XPosition = 3;
pointer->XPosition = 4;
referenz.XPosition = 5;

In allen Fällen wird die instanz verändert.

Referenzen kann man nicht deklarieren, es muss ihnen sofort etwas zugewiesen werden. Ab diesem Zeitpunkt ist die Arbeit mit der Referenz genauso, als würde man direkt mit der Instanz arbeiten. Man kann danach auch nicht mehr die Instanz „wechseln“, das Ziel einer Referenz ist also nach ihrer Initialisierung unveränderlich.

Deswegen wird in vielen Büchern beschrieben, dass eine Referenz ein Alias, also nur ein anderer Name für die gleiche Instanz, sei. Das ist soweit korrekt, aber lenkt vom eigentlichen Zweck von Referenzen ab.

Referenzen anwenden

Bisher haben wir gesehen, wie Referenzen definiert werden und sie gewissermaßen als Aliasnamen für im gleichen Scope existierende Instanzen verwendet. Das ist natürlich keine sinnvolle Anwendung, schließlich kann an so auch gleich die Instanz verwenden. Also wenden wir uns nun den sinnvollen Anwendungen zu.

Anwendungen