Funktionsüberladung so richtig?
-
hab das mal so gemacht, und wollte fragen ob es so richig und gut ist:
int max(int a,int b) { if(a<b) return b; else return a; } int max(int a,int b,int c) { if(max(a,b)<c) return c; else return max(a,b); } int max(int a,int b,int c,int d) { if(max(a,b,c)<d) return d; else return max(a,b,c); } double max(double a,double b) { if(a<b) return b; else return a; }
-
Ohne genau hinzugucken:
Ja stimmt so schon den Überladen heisst ja nichts anderes als unterschiedliche funktionen(in rückgabewerten, Argumentenarten und Anzahl) zuerstellen also eigentlich in Ordnung
-
MartinMilbret schrieb:
Ja stimmt so schon den Überladen heisst ja nichts anderes als unterschiedliche funktionen(in rückgabewerten, Argumentenarten und Anzahl) zuerstellen
Das stimmt so nicht ganz. Der Rückgabewert einer Funktion gehört nicht zu ihrer Signatur, weshalb man keine Funktionen, die sich nur im Rückgabewert unterscheiden, überladen kann.
Beispiel:
int f(double x, double y) { ... } double f(double x, double y) { ... } ... int main() { ... double z = f(9.9, 18.18); // Fehler - Mehrdeutiger Aufruf! ... }
Ansonsten ist deine Aussage aber korrekt.
Gruß Caipi
-
oben hat ja die double funktion auch andere parameter!
-
Ich weiß nicht genau wofür du das script verwenden willst aber wenn du int double und womöglich vielleicht auch noch char werte vergleichen willst und das bei unterschiedlicher anzahl der parameter würde ich nicht so viele funktionen überladen! Sondern lieber mit einem Template mit variabler Parameterliste arbeiten.
//template_variabel.cpp //ein template mit Variabler Parameterliste //das werte vergleicht mithilfe einer Rekursion //Storm 2006 //Für die Variable Parameterliste #include <cstdarg> //Für qsort() #include <cstdlib> //Für cout #include <iostream> //maximal 100 werte #define buffer 100 using namespace std; //##################Vergleichsfunktion für qsort#####################// int vergleich(const void *ptr1, const void *ptr2) { if( *(short *)ptr1 < *(short *)ptr2 ) return -1; else if( *(short *)ptr1 > *(short *)ptr2 ) return 1; else return 0; /* Beide Elemente sind gleich */ } //#########################Das Template###########################// namespace storm { //eigener namespace aufmachen template <class T> T max(T a, ...) { //Deklaration va_list argum_zeiger; //zeigt auf das jeweils nächste Argument short zaehler = 0; //zählt die Argumente T werte[buffer]; werte[zaehler] = a; //Jetzt die Werte auslesen und vergleichen va_start(argum_zeiger, a); while(werte[zaehler] != -1) { //Schleife zu auslesen (letzter wert muss immer -1 sein) zaehler++; //zähler wird incrementiert werte[zaehler] = va_arg(argum_zeiger, T); //aktueller Wert wird in array gespeichert } va_end(argum_zeiger); //argum_zeiger wird auf NULL zurückgesetzt qsort(werte, zaehler, sizeof(T), vergleich); //array werte wird nach größe soriert return werte[zaehler-1]; //gröster wert wird zurückgegeben }; //Template zu } //eigener namespace zumachen //#########################Ende##################################// int main() { int a, b, c, d = -1; int ergebnis; cin >> a; cin >> b; cin >> c; ergebnis = storm::max(a,b,c, d); cout << ergebnis << endl; return 0; }
Dabei muss das letzte Argument aber immer -1 sein!
Ob du jetzt jedoch int, double, float oder char übergibst ist völlig egal!
Dieses Script rechnet sich aber wahrscheinlich nur wenn du sehr viele Werte unterschiedlichstem Typ verglaichen willst.
-
Caipi schrieb:
MartinMilbret schrieb:
Ja stimmt so schon den Überladen heisst ja nichts anderes als unterschiedliche funktionen(in rückgabewerten, Argumentenarten und Anzahl) zuerstellen
Das stimmt so nicht ganz. Der Rückgabewert einer Funktion gehört nicht zu ihrer Signatur, weshalb man keine Funktionen, die sich nur im Rückgabewert unterscheiden, überladen kann.
Beispiel:
int f(double x, double y) { ... } double f(double x, double y) { ... } ... int main() { ... double z = f(9.9, 18.18); // Fehler - Mehrdeutiger Aufruf! ... }
Ansonsten ist deine Aussage aber korrekt.
Gruß Caipi
naja, so ganz korrekt ist das nicht. der begriff der signatur ist nicht standardisiert, der typ einer funktion wird bestimmt durch:
- den return typ (bzw. void)
- den typ ihrer parameter
- die cv-qualifikation im falle von memberfunktionen
- die exceptionspezifikationbeim überladen gibt es dann bestimmte regeln, die einschränkend wirken. eine davon ist, dass funktionen, die sich nur im return-typ unterscheiden, nicht überladen werden können. das macht dein beispiel illegal, aber nicht erst beim aufruf, bereits die deklaration ist ein fehler (allerdings ist die mehrdeutigkeit, die sich beim aufruf ergäbe, der grund für diese regel).
eine weitere regel ist z.b., dass memberfunktionen nicht mit einer statischen funktion mit denselben parametern überladen werden kann.
-
witzigerweise kann man funktionen, die sich nur in ihren exception-spezifikationen unterscheiden, überladen
Nope. Kann man nicht. Deshalb sagt man ja auch, dass Exception-Spezifikationen eine Art "Shadow-Type System" (vgl. Exceptional C++ Style) wären. Sie gehören nicht zum Typ, bis auf manchmal.
Nicht zum Typ gehören sie z.B. bei der Überladungsauflösung und in typedefs. Beim
Überschreiben von virtuellen Funktionen hingegen gehören sie zum Typ.Es gibt zum Thema auch einen Defect Report:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#92
-
camper schrieb:
Caipi schrieb:
MartinMilbret schrieb:
Ja stimmt so schon den Überladen heisst ja nichts anderes als unterschiedliche funktionen(in rückgabewerten, Argumentenarten und Anzahl) zuerstellen
Das stimmt so nicht ganz. Der Rückgabewert einer Funktion gehört nicht zu ihrer Signatur, weshalb man keine Funktionen, die sich nur im Rückgabewert unterscheiden, überladen kann.
Beispiel:
int f(double x, double y) { ... } double f(double x, double y) { ... } ... int main() { ... double z = f(9.9, 18.18); // Fehler - Mehrdeutiger Aufruf! ... }
Ansonsten ist deine Aussage aber korrekt.
Gruß Caipi
naja, so ganz korrekt ist das nicht. der begriff der signatur ist nicht standardisiert, der typ einer funktion wird bestimmt durch:
- den return typ (bzw. void)
- den typ ihrer parameter
- die cv-qualifikation im falle von memberfunktionen
- die exceptionspezifikationbeim überladen gibt es dann bestimmte regeln, die einschränkend wirken. eine davon ist, dass funktionen, die sich nur im return-typ unterscheiden, nicht überladen werden können.
Jup. Hast Recht. Habe mich undeutlich ausgedrückt. Wollte sagen, dass der Rückgabewert, (der zu der Funktions-Signatur gehört) beim Aufruf einer Funktion nicht ermittelt werden und man desshalb keine Funktionen, die sich nur im Rückgabewert unterscheiden, überladen kann.
das macht dein beispiel illegal, aber nicht erst beim aufruf, bereits die deklaration ist ein fehler (allerdings ist die mehrdeutigkeit, die sich beim aufruf ergäbe, der grund für diese regel).
Auch hier hast du Recht. Habe das im Code (aus Faulheit) nicht deutlicher erwähnt...
Gruß Caipi