# Default Parameter & Callback Funktionen?



## jccTeq (21. Februar 2005)

Hallo,

mal wieder ein Problem. Man kann einer Class ja Callback-Funktionen geben, indem man den Typ dieser Callback-Funktionen vorher per typedef benennt. Dort kann man ja auch angeben, daß diese Funktion Default-Parameter haben soll, also Parameter, die bei nicht vorhandensein in der Funktion einen Standard-Wert erhalten. 

int (*pBlaBlubb)(int ParamA, int ParamB, int ParamC = 10);

wobei bei einem Aufruf dieser Callback Funktion mit 

meinObjekt.Callback(20,30,40);

in der Funktion der Parameter ParamC den Wert 40 hätte. Beim Aufruf

meinObjekt.Callback(20,30);

hätte der hier nicht angegebene Parameter ParamC den Wert 10. Ich kann diesen Typ von Funktionaufruf ja nur mit Default-Parametern universell angeben, weil ich ja nicht weiß, auf was für eine Art die Funktion nun später aufgerufen wird. 

Das Problem ist nun folgendes:
ich versuche das Programm mit dem neuen Visual Studio .NET 2003 zu übersetzen. Der darin enthaltene Compiler *kann aber leider keine Default-Parameter mehr*. 

Ich müsste also Wrapper-Funktionen schreiben, die die eigentliche Funktion mit dem gewünschten Parameter-Set überlädt. 

Das Objekt meinObjekt enthält nun den Funktions-Zeiger "Callback", welcher auf die aufzurufende Funktion zeigt. Na? Ahnt ihr schon, worauf ich hinaus will? Wie sage ich dem Compiler nun, bzw. dem System, daß für die Funktion hinter Callback mehrere überladene Funktionen existieren, und welche davon es aufrufen muss? Der Zeiger Callback zeigt ja explizit auf eine der überladenen Funktionen. Diese hat aber eine feste Anzahl Parameter. Für diese Problematik haben wir halt Default-Parameter verwendet. Logischer Schritt. Aber was kommt jetzt, wo der neue Compiler diese nicht mehr unterstützt? Wie macht man sowas jetzt?

Danke!

Gruß, 
Hendrik


----------



## uhu01 (21. Februar 2005)

Hy!

Der VS unterstützt die Default Parameter auf jeden Fall noch immer.

Der Fehler den du machst, ist soweit ich das sagen kann, dass du den Pointer auf die Funktion nicht dereferenzierst. Du müsstest den pointer eigentlich vorher dereferenzieren:

```
(*meinObjekt.Callback)(20,30);
```
Vorausgesetzt ich hab das richtig verstanden und du hast:

```
int Funktion( int, int, int);

class CMeineKlasse {
  ...
  int (*Callback)( int, int, int);
  ...
}

int Funktion( int a_, int b_, int c_ = 10) {
  ...
  Berechnungen...
  ...
}
```
Und irgendwann ( z.B. im Konstruktor) setzt du dann CMeineKlasse::Callback = Funktion;
Dann kannst du die Callback so aufrufen wie oben beschrieben.

Hoffe das ich dir helfen konnte.

Bitte korrigiert mich wenns falsch is.

mfg
uhu01


----------



## jccTeq (21. Februar 2005)

Das weiß ich wohl, sorry, war mehr oder weniger Pseudo-Code, den ich da verzapft hab, oben. Hätte ich dazu schreiben sollen. Mein Fehler. 

Der Compiler meckert die Benutzung von Default-Parametern explizit an. Ich kann die die Fehlermeldung gern zeigen: 


```
typedef int (WINAPI *tpsMMLCallback)(const class CIdfRecord&, void* param=0, class CJob* aJob=0);
```


```
error C2383: 'tpsMMLCallback' : default-arguments are not allowed on this symbol
```

Link zum Fehler: 
http://msdn.microsoft.com/library/d...en-us/vccore/html/vcerrCompilerErrorC2383.asp


----------



## uhu01 (21. Februar 2005)

Hy!

Seit wann muss man muss man vor dem Typ class schreiben, bei mir gehts ohne.
Aja und du musst die Default Parameter in der Implemetierung der Funktion angeben, nicht in der Typedef.

mfg
uhu01


----------



## jccTeq (21. Februar 2005)

Ich muss zu meiner Verteidigung sagen, daß ich den Code so nicht selbst geschrieben habe, sondern ein Kollege von mir. 

Also so wie du das beschreibst, weiß der Compiler auch bei Callback Funktionen, welche überladene Funktion er aufrufen muss, selbst wenn der Zeiger auf eine andere Überladung zeigt?

Also so:


```
void funktion_a(int bla, int blubb, int bli) // Überladung 1
{
    macht_irgendwas();
}

void funktion_a(int bla, int blubb) // Überladung 2
{
    macht_was_anderes();
}

int main()
{
    meinObjekt.Callback = funktion_a;
}
```

Beziehungsweise so


```
void funktion_a(int bla, int blubb, int bli = 10) // Überladung 1
{
    macht_irgendwas();
}

int main()
{
    meinObjekt.Callback = funktion_a;
}
```

Aha... jetzt fällt es mir wie Schuppen von den Augen. Er geht ja nach dem Funktionsnamen und da dann nach der Form des Aufrufs über den Funktions-Zeiger Callback. Also: 


```
(*mainObjekt.Callback)(10,20,30); // ruft in Bsp.1 Überladung 1 auf mit bli = 30, in Bsp.2 Überladung 1 mit bli = 30
    (*mainObjekt.Callback)(10,20); // ruft in Bsp.1 Überladung 2 auf ohne bli, in Bsp.2 Überladung 1 mit bli = 10
```

richtig?


----------



## uhu01 (21. Februar 2005)

Hy!

Nein das hab ich nicht gemeint. Ich hab gemeint das du nicht

```
typedef int (WINAPI *tpsMMLCallback)(const class CIdfRecord&, void* param=0, class CJob* aJob=0);

sondern
typedef int (WINAPI *tpsMMLCsallback)( const CldfRecord&, void*, CJob*)

und in der Implementierung
int fMeineFunktion( const CldfRecord& aldfRecord, void* param=0, CJob* aJob=0) {
  ...
}
```

das hab ich gemeint, tschuldige wenn ich mich unverständlich ausgedrückt hab.

mfg
uhu01


----------



## jccTeq (21. Februar 2005)

So hatte ich das auch verstanden. 

Das Problem, was jetzt auf uns zukommt, ist die Korrektur dieses Fehlers. Ein mords Aufwand, weil wir das an mächtig vielen Stellen offenbar falsch gemacht haben, obwohl's ja funktioniert, mit dem alten Compiler.


----------



## uhu01 (21. Februar 2005)

Hy!

Probiers vielleicht vorher im kleinen Rahmen aus, damit du nicht das ganze Prog. änderst, und dann draufkommst dass es erst nicht funktioniert.

mfg
uhu01


----------

