Wenn fertig, bitte Fenster schließen

Funktionszeiger

Ok, begeben wir uns in die Tiefen der C++ Programmierung! In einem Funktionszeiger können, wie unschwer zu erraten ist, Adressen von Funktionen abgelegt werden.

Definition eines Funktionszeigers

Sehen wir uns zunächst die Definition eines Funktionszeigers an. Die Definition eines Funktionszeigers gleicht prinzipiell der Deklaration einer Funktion, deren Adresse später im Zeiger abgelegt werden soll. Nur dass jetzt anstelle des Funktionsnamens der Name des Funktionszeigers innerhalb einer Klammer steht. Somit kann ein Funktionszeiger auch nur Adressen von Funktionen aufnehmen, die im Returntyp und in der Anzahl und Art der Parameter mit der Zeigerdefinition übereinstimmen.

PgmHeader
// Zeiger auf Funktionen vom Typ
//     void Func();

void (*pfnFunc1)();
// Zeiger auf Funktionen vom Typ
//     short Func(short, char*);

short (*pfnFunc2)(short, char*);

Im Funktionszeiger pfnFunc1 können nur Adressen von Funktionen ablegt werden, die keinen Parameter besitzen und auch keinen Returnwert liefern. Der Zeiger pfnFunc2 hingegen kann nur Adressen von Funktionen aufnehmen, die als ersten Parameter einen short-Wert und als zweiten Parameter einen char-Zeiger erwarten. Zusätzlich müssen die Funktionen noch einen short-Wert als Returnwert besitzen.

Bilden einer Funktionsadresse

Nach dem der Funktionszeiger definiert ist, kann ihm die Adresse einer entsprechenden Funktion zugewiesen werden. Um die Adresse einer Funktion zu erhalten wird einfach der Name der entsprechenden Funktion angegeben, d.h. es darf hier kein Adressoperator & stehen.

PgmHeader
// Funktionsdeklarationen
void DoSomething();
short DoAnything(short, char*);
// Zeigerdefinition ohne decltype
void (*pfnFunc1)();
short (*pfnFunc2)(short, char*);
// Adresse der Funktion zuweisen
pfnFunc1 = DoSomething;
pfnFunc2 = DoAnything; 

Steht die Funktionsdeklaration vor der Definition des Funktionszeigers, dann kann der Funktionszeiger auch mit Hilfe von decltype() definiert werden, was die Lesbarkeit deutlich erhöht.

PgmHeader
// Funktionsdeklarationen
void DoSomething();
short DoAnything(short, char*);
// Zeigerdefinition mit decltype
decltype(DoSomething) *pfnFunc1
decltype(DoAnything) *pfnFunc2;
// Adresse der Funktion zuweisen
pfnFunc1 = DoSomething;
pfnFunc2 = DoAnything; 

Funktionsaufruf über Funktionszeiger

So, bleibt zum Schluss nur noch die Frage offen, wie die Funktion aufgerufen wird deren Adresse im Zeiger abgelegt ist. Wie bekannt sein sollte, erfolgt der Zugriff auf Speicherstellen über Zeiger durch den Dereferenzierungsoperator *. Und genauso funktioniert auch der Aufruf von Funktionen über Funktionszeiger. Nur muss der dereferenzierte Funktionszeiger jetzt innerhalb einer Klammer stehen. Erhält die aufzurufende Funktion noch Parameter, so sind diese, wie bei einem normalen Funktionsaufruf, in einer weiteren Klammer anzugeben.

PgmHeader
// Zeigerdefinition
void (*pfnFunc1)();
short (*pfnFunc2)(short, char*);
...
// Funktionsaufrufe
(*pfnFunc1)();
short nErg = (*pfnFunc2)(var, text);

BeispielUnd hier geht's zum Beispiel.