Ich suche eine elegante Möglichkeit, um das Umschreiben einer Funktion zu vermeiden, deren Implementierung fast gleich ist, aber nur die Signatur (die Anzahl der Eingangsparameter und deren Datentypen) ist unterschiedlich. Ich weiß, dass das Überladen von Funktionen in C nicht möglich ist. Ich weiß auch, dass variadische Funktionen existieren. Aber ich denke, dass sie in dieser Situation nicht hilfreich sein werden.Alternativen zum Funktionsüberladen in C
Betrachten Sie das folgende Problem, wo wir die Fläche eines Dreiecks berechnen müssen. Wir haben zwei Funktionen, die zwei verschiedene Formeln implementieren: S = 1/2bh und S = sqrt (s (s-a) (s-b) (s-c)). Abgesehen von der Berechnung des Bereichs ändert jede der Funktionen auch einen Parameter nb
oder nthr
. Schließlich gibt es eine Top-Level-Routine bisect_area_...
, die eine Bisektionsprozedur für eine gegebene Funktion area_tria1
oder area_tria2
startet und sie für einen Parameter nb
oder optimiert. Derzeit implementiere ich explizit zwei Bisektionsfunktionen: eine für die Signatur von area_tria1
und eine weitere für area_tria2
. Ich denke, dass es eine bessere, elegantere Art geben muss, die eine einzige generische Halbierungsfunktion ermöglichen würde bisect_area_tria()
. Bitte beachten Sie, dass die Eingabeparameter-Datentypen im realen Fall ebenfalls unterschiedlich sind.
Unten ist ein Skelett Pseudo-Code der Funktion Unterschriften:
// Calculate area of triangle, modify and return parameter 'nb'
void area_tria1_nb(..., int *nb, double b, double h, double *S) {
// change parameter 'nb'
...
S = 0.5*b*h;
}
// Calculate area of triangle, modify and return parameter 'nthr'
void area_tria1_nthr(..., int *nthr, double b, double h, double *S) {
// change parameter 'nthr'
...
S = 0.5*b*h;
}
// Optimise calculation of area of triangle, for parameter 'nb' or 'nthr'
void bisect_area_tria1(..., double b, double h, double *S, int (*area_tria1)(double, double)) {
}
// Calculate area of triangle, modify and return parameter 'nb'
void area_tria2_nb(..., int *nb, double a, double b, double c, double *S) {
// change parameter 'nb'
...
S = sqrt(s*(s-a)*(s-b)*(s-c));
}
// Calculate area of triangle, modify and return parameter 'nthr'
void area_tria_2_nthr(..., int *nthr, double a, double b, double c, double *S) {
// change parameter 'nthr'
...
S = sqrt(s*(s-a)*(s-b)*(s-c));
}
// Optimise calculation of area of triangle, for parameter 'nb' or 'nthr'
void bisect_area_tria2(..., double a, double b, double c, double *S, int (*area_tria2)(double, double, double)) {
}
void main() {
bisect_area_tria1(..., &nb, b, h, &S, area_tria1_nb);
bisect_area_tria1(..., &nthr, b, h, &S, area_tria1_nthr);
bisect_area_tria2(..., &nb, a, b, c, &S, area_tria2_nb);
bisect_area_tria2(..., &nthr, a, b, c, &S, area_tria2_nthr);
}
"Vermeidung von Code-Duplizierung" und "Funktionsüberladung" haben wenig miteinander zu tun. –
'void area_tria1_nb (..., int * nb, doppeltes b, doppeltes h, double * S)' sicher, dass dies kein gültiger Prototyp ist. –
Als eine Art vager Kommentar ...Vielleicht erlaubt es Ihnen der Polymorphismus, eine einzige Funktion zu benutzen, um die etwas unterschiedlichen Verhaltensweisen auszuführen, die Sie wollen. – byxor