Syntax
Definition der Default-Parameter
Aufruf der Funktion
Funktionserweiterung durch Default-Parameter
Beispiel und Übung
|
|
C++ erlaubt es, Parameter mit Defaultwerten zu belegen. Parameter die mit einem Defaultwert versehen sind, können beim Aufruf der Funktion weggelassen werden. In diesem Fall erhält dann die Funktion für den Parameter den angegebenen Defaultwert.
Um einen Parameter mit einem Defaultwert zu versehen, wird nach dem Parameternamen der Zuweisungsoperator angegeben, gefolgt vom Defaultwert. Im Beispiel wird der letzte Parameter symbol z.B. mit dem Defaultzeichen '#' belegt. Zu den dann möglichen Aufrufen der Funktion kommen wir gleich noch.
|
void DrawRect(short xPos, short yPos, short width, short height, char symbol = '#') { ... } |
Die Anzahl der Default-Parameter ist nicht begrenzt, jedoch ist dabei Folgendes zu beachten: erhält ein Parameter einen Defaultwert, so müssen alle rechts davon stehenden Parameter ebenfalls einen Defaultwert besitzen. Dies sollten Sie bereits bei der Spezifikation der Funktion beachten. Als Defaultwerte sind nur Literale oder Konstanten zugelassen. Und selbstverständlich muss der Datentyp des Defaultwertes mit dem Datentyp des Parameters übereinstimmen. Das erste nachfolgende Beispiel ist in Ordnung, erhalten die Parameter height und symbol jeweils einen Defaultwert. Das zweite Beispiel hingegen ist fehlerhaft. Der Parameter height erhält hier ebenfalls einen Defaultwert, aber der rechts davon befindliche Parameter symbol keinen. Und das ist nicht zulässig.
|
// Das ist in Ordnung void DrawRect(short xPos, short yPos, short width, short height = 1, char symbol = '#') { ... } // Aber dies erzeugt einen Fehler void DrawRect(short xPos, short yPos, short width, short height = 1, char symbol) { ... } |
Die Angabe der Default-Parameter kann wie dargestellt auf zweierlei Arten erfolgen:
Sie dürfen den Default-Parameter nur einmal angeben, d.h. entweder bei der Deklaration oder bei der Definition.
|
// Default-Parameter bei der Deklaration // Deklaration void DrawRect(short xPos, short yPos, short width, short height = 1, char symbol = '#'); // Definition void DrawRect(short xPos, short yPos, short width, short weight, char symbol) { ... } // Default-Parameter bei der Definition // Deklaration void DrawRect(short xPos, short yPos, short width, short height, char symbol); // Definition void DrawRect(short xPos, short yPos, short width, short height = 1, char symbol = '#') { ... } |
Geben Sie die Default-Parameter aber nach Möglichkeit bei der Deklaration an. In der Regel werden Sie Deklarationen bei größeren Projekten in einer Header-Datei vornehmen, die dann von den entsprechenden Modulen eingebunden wird, die die Funktion verwenden. Und nur wenn die Default-Parameter in dieser Header-Datei stehen, sind sie auch in allen Modulen auch bekannt.
Sehen wir uns nun den Aufruf einer Funktion mit fünf Parametern an, wobei die letzten zwei Parameter einen Defaultwert besitzen. Der erste Aufruf übergibt an die Funktion nur 3 Parameter. Die beiden fehlenden Parameter height und symbol werden dann mit den Defaultwerten belegt während der zweite Aufruf nun zusätzlich die Höhe height übergibt
|
// Funktionsdefinition void DrawRect(short xPos, short yPos, short width, short height = 1, char symbol = '#') { ... } // Erlaubte Aufrufe DrawRect(10,10,100); // entspricht dem Aufruf DrawRect(10,10,100,1,'#') DrawRect(10,10,100,100); // entspricht dem Aufruf: DrawRect(10,10,100,100,'#') // Aber dies ist nicht erlaubt! // DrawRect(10,10,100,,'*'); |
Eines müssen Sie noch beim Aufruf von Funktionen mit Defaultparametern beachten. Wird beim Aufruf für einen der Parameter mit einem Defaultwert explizit ein Wert übergeben, so müssen für alle links davon stehenden Parameter ebenfalls Werte übergeben werden. Beim letzten Aufruf im Beispiel oben wird für für den letzten Parameter explizit ein Wert vorgegeben und damit müssen für alle links davon stehenden Parameter ebenfalls Werte angegeben werden.
Zum Abschluss dieser Lektion (das Beispiel und die Übung kommen aber gleich noch) noch ein kleiner Tipp.
Default-Parameter eignen sich auch hervorragend dazu, eine bereits bestehende Funktion zu erweitern. Sehen Sie sich das Ausgangsbeispiel an. Das Beispiel enthält eine Funktion SortIt(...), die ein char-Feld in aufsteigender Reihenfolge sortieren soll.
|
// Funktionsdeklaration void SortIt(char* array); // main() Funktion int main() { ... SortIt(myArray); ... } // Funktionsdefinition void SortIt(char* array) { ... //aufsteigend sortieren } |
In weiteren Verlaufe der Programmentwicklung stellt sich nun die Anforderung, dass das char-Feld auch wahlweise in fallender Reihenfolge sortiert werden soll. Hierzu muss der Funktion ein neuer Parameter übergeben werden, der die Sortierrichtung beschreibt. Damit aber wären dann auch alle bisherigen Funktionsaufrufe entsprechend zu korrigieren.
Mithilfe von Default-Parameter ist es jetzt jedoch möglich, lediglich die Funktion an die neue Anforderung anzupassen und bereits bestehende Funktionsaufrufe unverändert zu lassen.
Dazu wird der für die Sortierrichtung notwendige Parameter mit einem Defaultwert versehen, der die aufsteigende Sortierrichtung definiert. Wie Sie in der Zwischenzeit ja wissen, können beim Funktionsaufruf Parameter mit Defaultwerten weggelassen werden. D.h. wird die Funktion, wie bisher gewohnt, mit nur einem Parameter aufgerufen, wird das char-Feld aufsteigend sortiert. Soll das Feld dagegen fallend sortiert werden, so ist beim Aufruf der Funktion ein vom Defaultwert abweichender Wert anzugeben.
|
// Funktionsdeklaration void SortIt(char* array, bool dir = true); // main() Funktion int main() { ... SortIt(myArray); // aufsteigend sortieren ... SortIt(myArray, false); // fallend sortieren } // Funktionsdefinition void SortIt(char* array, bool dir) { if (dir) ... // aufsteigend sortieren else ... // fallend sortieren } |
|
|
Daten (L: 10 B: 11 H: 12) |
|
// Beispiel zu Default-Parameter // Zuerst Dateien einbinden #include <iostream> using std::cout; using std::endl; // Deklaration der Funktion zur Berechnung des Rauminhalts unsigned long CalcCube (unsigned short lenght, unsigned short width, unsigned short height=1); // main() Funktion int main() { // Rauminhalt berechnen cout << "Rauminhalt: " << CalcCube(10,11,12) << endl; // Fläche berechnen cout << "Fläche: " << CalcCube(10,11) << endl; } // Funktion: CalcCube // Eingang : Länge, Breite, Höhe des Körpers // Ausgang : Rauminhalt der Körpers unsigned long CalcCube(unsigned short length, unsigned short width, unsigned short height) { cout << "Daten (L: " << length; cout << " B: " << width; cout << " H: " << height << ")\n"; return length * width * height; } |
Erstellen Sie eine Klasse zur Darstellung eines Rechtecks. Ein Rechteck soll die Eigenschaften Länge, Breite, Position und Farbe besitzen, wobei sich die Farbinformation wiederum aus einen Rot-, Grün- und Blauanteil zusammensetzt. Die Farbeigenschaften sind als unsigned char Daten abzulegen und alle anderen Eigenschaften als short Daten.
Das Rechteck soll verschoben und in seiner Größe verändert werden können. Zusätzlich soll noch die Farbe des Rechtecks einstellbar sein.
Desweiteren ist eine Memberfunktion zu schreiben, um das Rechteck darzustellen. Da wir hier aber keine Grafik-Programmierung betreiben wollen, sind lediglich die Eigenschaften des Rechtecks (so wie unten dargestellt) auszugeben.
Um die Eigenschaften des Rechtecks zu initialisieren ist eine entsprechende Memberfunktion zu verwenden. Hierbei soll es möglich sein, auch ein Rechteck ohne Angabe einer Farbinformation anzulegen. In diesem Fall sind die Farbinformationen mit den Defaultwert 0x00 zu belegen.
Legen Sie zwei Rechtecke an, ein globales und ein lokales innerhalb der main() Funktion. Das globale Rechteck soll die Standardfarbe erhalten.
Geben Sie beide Rechtecke aus. Anschließend ist das erste Rechteck zu verschieben und das zweite in seiner Größe und Farbe zu verändern. Geben Sie zur Kontrolle die veränderten Rechtecke erneut aus.
Diese Übung sollte Ihnen eigentlich bekannt vorkommen. Sie wurde in ähnlicher Form in der Lektion über Klassen schon aufgeführt.
|
1. Rechteck: |