D – die neue Programmiersprache mit C++-Wurzeln

Seite 4: Operatoren ĂĽberladen

Inhaltsverzeichnis

Auch die D-Schöpfer konnten den Verlockungen des Operatorüberladens nicht widerstehen. Allerdings gestaltet sich das Überladen etwas anders als etwa in C++. Operatoren wie + sind in der Sprache über Methoden wie opAdd repräsentiert. Wer den Operator überladen will, definiert daher eine entsprechend benannte Methode. |#l10]Listing 10[/anchorlink] implementiert eine Klasse MyNumber und überlädt dort zur Veranschaulichung die Operatoren == sowie +.

In Hinblick auf Felder bietet D alle aus C++ bekannten Möglichkeiten inklusive Zeigern, die sich von ihren C-Brüdern auf dem ersten Blick kaum unterscheiden. Das ändert sich aber auf den zweiten, etwas detaillierteren Blick. Felder besitzen zum Beispiel implizite Methoden, etwa zur Längenprüfung:

int [3] a;
writefln(a.length); // liefert 3

Statische Felder wie im Beispiel haben eine feste Länge, während solche ohne Längenangabe dynamische Felder darstellen, etwa int[] a. Zusätzlich zu dieser C++-typischen Postfixnotation kennt D die Präfixnotation: int a[]. Zu erwähnen ist an dieser Stelle, dass D Zeichenketten als Felder von Buchstaben betrachtet (char[]). Vorteilhaft und mächtig sind die diversen Array-Operationen, etwa zum Kopieren von Feldern, für das Erzeugen von Feldteilmengen (Slices) sowie für Feldkonkatenation und Feldinitialisierung:

int [7] a = [ 1,2,3,4,5,6,7 ];

int [5] b = 3; // => b[0] = b[1] = b[3] = 3; int [] slice = a[2..4]; // slicing ergibt [3,4] int [] copy = a; int [] concat = a ~ b; // konkateniert Felder [/pre]

Zudem unterstützt D die aus C++ bekannten unregelmäßigen Felder (Jagged Arrays). Bei double [][] matrix handelt es sich um ein solches Feld von Zeigern auf Felder. Weil die Längen der referenzierten Felder unterschiedlich sein können, ist hier von unregelmäßigen Feldern die Rede. Aber auch regelmäßige stellt D bereit, etwa in double[4][4] matrix. Hier handelt es sich demzufolge um eine vier mal vier Zahlen umfassende zweidimensionale Matrix.

Als weitere Spielart dienen assoziative Felder. Wie in C#-Hash-Tabellen lassen sich durch Nutzung des Index-Operators SchlĂĽssel auf Werte abbilden:

int[char[]] hashTable;
hashTable["Adams"] = 42;
writefln(hashTable["Adams"]); // liefert 42

Als nützlich erweisen sich die in D unterstützten variablen Parameterlisten. In C++ ist schon seit Längerem unter dem Begriff variadic templates eine auf Templates basierende Lösung geplant, die Teil des neuen C++-Standards sein soll (siehe S. 60). Das folgende Beispiel demonstriert neben einer variablen Parameterliste die foreach-Schleife zur Iteration über Aggregat-Strukturen.

void f(...) {
foreach(a; _arguments)
writefln(a);
}
void main() {
f(2, 1.1, "aber");
} // resultiert in der Ausgabe von:
// int double char[]

Es wäre noch über viele Spracheigenschaften zu berichten, etwa über reguläre Ausdrücke, den reichhaltigen Satz an String-Funktionen, die integrierte Unterstützung für Unit-Tests, die Nutzung des Schlüsselworts synchronized, um Objekte oder Methoden Thread-sicher zu machen, die Attribute out und inout zum Spezifizieren der Transportrichtung bei Parametern, Design-by-Contract mit Pre- und Post-Conditions, explizites Konvertieren von Datentypen mit dem cast-Operator, das Überladen von Operatoren in D, „Nested Classes“, Inline-Integration von Assemblercode oder die im Vergleich zu C++ reichhaltigere Menge einfacher Datentypen. Das würde allerdings den Rahmen dieses Artikels sprengen und sei nur als Anreiz zur eigenen Vertiefung erwähnt.