C++ Kurs

Default-Parameter

Die Themen:

Syntax
Definition der Default-Parameter
Aufruf der Funktion
Funktionserweiterung durch Default-Parameter
Beispiel und Übung

Syntax

Die nachfolgenden Ausführungen beziehen sich sowohl auf Memberfunktionen wie auch auf Funktionen. Wenn im Folgenden von Funktionen gesprochen wird, so sind damit stets auch Memberfunktionen gemeint.

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)
{
   ...
}

Definition der Default-Parameter

Die Angabe der Default-Parameter kann wie dargestellt auf zweierlei Arten erfolgen:

  1. Bei der Deklaration der Funktion/Memberfunktion
  2. oder bei der Definition der Funktion/Memberfunktion

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.

Aufruf der Funktion

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.

Funktionserweiterung durch Default-Parameter

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
}

Beispiel und Übung

Beispiel:

Im Beispiel wird eine Funktion zur Berechnung der Fläche eines Rechtecks oder des Rauminhalts eines Quaders verwendet. Der 'Trick', der hierbei verwendet, wird besteht darin, dass die Fläche zahlenmäßig dem Rauminhalt entspricht, wenn für die Höhe der Wert 1 eingesetzt wird. Demzufolge wird für den Höhen-Parameter als Defaultwert 1 vorgegeben.

Daten (L: 10 B: 11 H: 12)
Rauminhalt: 1320
Daten (L: 10 B: 11 H: 1)
Fläche: 110


// 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;
}

Übung:

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:
Position: 10,10
Grösse : 640,480
RGB-Wert: 0,0,0
2. Rechteck:
Position: 100,50
Grösse : 800,600
RGB-Wert: 0x80,0x80,0x80
1. Rechteck:
Position: 20,20
Grösse : 640,480
RGB-Wert: 0,0,0
2. Rechteck:
Position: 100,50
Grösse : 1024,786
RGB-Wert: 0xc0,0xc0,0xc0

Lösung ansehen!