Forum: Compiler & IDEs Überladung Funktionen


von Christian A. (see0jay)


Lesenswert?

Hätt ein paar Fragen:

Hab hier eine Library wo Funktionen überladen sind.
Beispielsweise:
1
void USB::print(char c)
2
{
3
  printByte(c,  _uart);
4
}
5
6
void USB::print(const char c[])
7
{
8
  printString(c,  _uart);
9
}
10
11
void USB::print(uint8_t b)
12
{
13
  printByte(b,  _uart);
14
}

Wie entscheidet der Compiler, welche Funktion aufgerufen wird? Geht er 
da nach dem Datentypen?

Bei den Funktionen handelt es sich ja um eine C++ Notation.
Herrscht da ein Unterschied zur c-Notation? Hab versucht in meinem main 
File andere Funktionen zu überladen, da gab es teilweise Fehler.

greets
see0jay

von nocheinGast (Gast)


Lesenswert?

In C++ nimmt der Compiler die Funktion, deren Parameter-Datentypen zum 
Aufruf passen (oder implizit konvertierbar sind), und wenn das mehrere 
sind, gibts einen Fehler, z. B. "Mehrdeutiger Aufruf einer überladenen 
Funktion".
Dann kann man immer noch explizit casten, z.b. 
"USB::print((uint8_t)'A');".

In C gibts auch einen Fehler. Da kann man nämlich keine Funktionen 
überladen...

von Brater (Gast)


Lesenswert?

Das wird ja irgendwo auch klar: ein Char ist etwas anderes als dein Char 
[] Parameter (sollte eigentlich besser ein char * sein oder noch besser: 
ein char const * const). Ein Zeiger wiederrum lässt sich von einem int 
unterscheiden, da der Zeiger eine Speicheradresse enthält.

wegen C und überladene Funktionen: ich würde behaupten: wenn man nicht 
wirklich explizit in einen C-only Modus schaltet, sind fast immer auch 
Cpp Features möglich.

von nocheinGast (Gast)


Lesenswert?

1
#include <stdio.h>
2
3
void test(int i) {
4
}
5
6
void test(double d) {
7
}
8
9
int main() {
10
  return 0;
11
}
1
ich@VirtualBox:~$ gcc -o test test.c
2
test.c:6:6: Fehler: In Konflikt stehende Typen für »test«
3
test.c:3:6: Anmerkung: Vorherige Definition von »test« war hier
4
ich@VirtualBox:~$ gcc -std=c90 -o test test.c
5
test.c:6:6: Fehler: In Konflikt stehende Typen für »test«
6
test.c:3:6: Anmerkung: Vorherige Definition von »test« war hier
7
ich@VirtualBox:~$ gcc -std=gnu90 -o test test.c
8
test.c:6:6: Fehler: In Konflikt stehende Typen für »test«
9
test.c:3:6: Anmerkung: Vorherige Definition von »test« war hier
10
ich@VirtualBox:~$ gcc -std=gnu99 -o test test.c
11
test.c:6:6: Fehler: In Konflikt stehende Typen für »test«
12
test.c:3:6: Anmerkung: Vorherige Definition von »test« war hier
13
ich@VirtualBox:~$ gcc -std=gnu11 -o test test.c
14
test.c:6:6: Fehler: In Konflikt stehende Typen für »test«
15
test.c:3:6: Anmerkung: Vorherige Definition von »test« war hier

Keine Chance, du brauchst einen echten C++-Compiler, und zumindest in 
der GCC sind das zwei verschiedene Programme.

von Oliver (Gast)


Lesenswert?

Brater schrieb:
> ich würde behaupten

Behaupten kannst du viel, nur stimmen wird es selten...

C und C++ sind zwei verschiedene Sprachen, und  beim gcc, um den es hier 
im Forum geht, sind der C- und der C++-Compiler auch zwei verschiedene 
Programme. Der eine kann nur und auschliesslich normgerechtes C, der 
andere nur und auschliesslich normgerechtes C++.

Und bei allen anderen ernsthaften C/C++-Compilern ist es genauso.

Oliver

von Marwin (Gast)


Lesenswert?

Eines der vielen C++-Features, die im Lehrbuch total toll sind, sich in 
der Praxis aber schnell als Quelle fuer Chaos und Verderben erweisen. 
Spaetestens wenn man auch bool und const verwendet, macht der Compiler 
nur noch selten das, was man sich vorestellt... und einen echten Vorteil 
bringt es eigentlich nicht.

von Hans Ulli K. (Gast)


Lesenswert?

Der Compiler entscheidet anhand der Datentypen innerhalb des Prototypen. 
Allerdings hast du da einige Aliasing-Effekte.

So wird er
void USB::print(char c);
void USB::print(uint8_t b);
nicht unterscheiden können.

Näheres kannst du aber bei Scott Meyers nachlesen.

von (prx) A. K. (prx)


Lesenswert?

Hans Ulli Kroll schrieb:
> void USB::print(char c);
> void USB::print(uint8_t b);
> nicht unterscheiden können.

char
signed char
unsigned char

sind 3 formal verschiedene Datentypen, auch wenn 2 davon das gleiche 
Zahlenformat bezeichnen.

von Oliver (Gast)


Lesenswert?

Marwin schrieb:
> Eines der vielen C++-Features, die im Lehrbuch total toll sind, sich in
> der Praxis aber schnell als Quelle fuer Chaos und Verderben erweisen.

Eins der vielen C++-Features, die, richtig angewendet, sich in der 
Praxis als unverzichtbar erweisen...

Oliver

von Karl H. (kbuchegg)


Lesenswert?

Oliver schrieb:
> Marwin schrieb:
>> Eines der vielen C++-Features, die im Lehrbuch total toll sind, sich in
>> der Praxis aber schnell als Quelle fuer Chaos und Verderben erweisen.
>
> Eins der vielen C++-Features, die, richtig angewendet,
                                     ******************

Das ist der springende Punkt.
Man muss halt wissen was man tut und das besser auch in den intimen 
Details - sprich: man sollte die Sprache schon gut kennen. Mit dem 
Studium von 3 halbseidenen Tutorien ist es nicht getan, wenn man sich 
fragt, warum hier ...
1
void foo( int i )
2
{
3
  std::cout << "foo_1" << std::endl;
4
}
5
6
void foo( char* j )
7
{
8
  std__cout << "foo_2" << std::endl;
9
}
10
11
int main()
12
{
13
  foo( NULL );
14
}

... "foo_2" ausgegeben wird und nicht wie fälschlich erwartet "foo_1"

> sich in der
> Praxis als unverzichtbar erweisen...

Solange sich bei der Überladung der Funktionen die Anzahl der Argumente 
jedesmal unterscheidet, ist dieses Feature super. Ist dem nicht so, muss 
man vorsichtig sein. Auch in C++ kann man sich wunderbar ins eigene Knie 
schiessen. Zwar eleganter als in C, aber das Ergebnis ist dasselbe.

von (prx) A. K. (prx)


Lesenswert?

Karl Heinz Buchegger schrieb:
> ... "foo_2" ausgegeben wird und nicht wie fälschlich erwartet "foo_1"

... oder "foo_1" und nicht wie fälschlich erwartet "foo_2". :-)

von Ich (Gast)


Lesenswert?

Das nennt sich nicht Funktion sondern Methode.

Die Unterscheidung findet durch die Signatur statt.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Mit dem
> Studium von 3 halbseidenen Tutorien ist es nicht getan, wenn man sich
> fragt, warum hier ...
>
> ...
>   foo( NULL );
> ...
>
> ... "foo_2" ausgegeben wird und nicht wie fälschlich erwartet "foo_1"

A. K. schrieb:
> ... oder "foo_1" und nicht wie fälschlich erwartet "foo_2". :-)

Oder "error: call of overloaded ‘foo(NULL)’ is ambiguous" und nicht wie
fälschlich erwartet "foo_1" oder "foo_2" ;-)

von Marwin (Gast)


Lesenswert?

Oliver schrieb:
> Eins der vielen C++-Features, die, richtig angewendet, sich in der
> Praxis als unverzichtbar erweisen...

Zeige doch mal einen Fall, wo dieses Feature unverzichtbar ist?

von (prx) A. K. (prx)


Lesenswert?

Yalu X. schrieb:
> Oder "error: call of overloaded ‘foo(NULL)’ is ambiguous" und nicht wie
> fälschlich erwartet "foo_1" oder "foo_2" ;-)

So wirds auch sein, wenn der Standard NULL als nullptr definiert. So wie 
GCC schon seit langer Zeit dafür einen eigenen Datentyp über das Keyword 
__null verwendet, an Stelle von Stroustrups 0.

von Karl H. (kbuchegg)


Lesenswert?

A. K. schrieb:
> Karl Heinz Buchegger schrieb:
>> ... "foo_2" ausgegeben wird und nicht wie fälschlich erwartet "foo_1"
>
> ... oder "foo_1" und nicht wie fälschlich erwartet "foo_2". :-)


:-)
Da bin ich beim Schreiben selbst reingefallen.

Danke für den Catch.

von Karl H. (kbuchegg)


Lesenswert?

Yalu X. schrieb:

> Oder "error: call of overloaded ‘foo(NULL)’ is ambiguous" und nicht wie
> fälschlich erwartet "foo_1" oder "foo_2" ;-)

Macht der gcc das bereits?
IMHO ist da zur Zeit, mit der jetzigen C++ Definition nichts ambigous.

von (prx) A. K. (prx)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Macht der gcc das bereits?

Seit Version 2.8 definiert GCC/C++ NULL als __null.

von Karl H. (kbuchegg)


Lesenswert?

Marwin schrieb:
> Oliver schrieb:
>> Eins der vielen C++-Features, die, richtig angewendet, sich in der
>> Praxis als unverzichtbar erweisen...
>
> Zeige doch mal einen Fall, wo dieses Feature unverzichtbar ist?

Konstruktoren mit unterschiedlichen Argumentlisten.

Unverzichtbar ist das falsche Wort. Man kann sich um alles drum rum 
programmieren. Aber so manche Überladung kann dann schon um einiges 
einfacher sein, als das drum rum programmierte. Speziell bei Templates 
wirds ansonsten manchmal haarig.

von (prx) A. K. (prx)


Lesenswert?

Karl Heinz Buchegger schrieb:
> IMHO ist da zur Zeit, mit der jetzigen C++ Definition nichts ambigous.

Nur gibts noch zu wenige Compiler für C++11. In GCC 4.7 ist das noch 
experimental.

von Rolf M. (rmagnus)


Lesenswert?

Ich schrieb:
> Das nennt sich nicht Funktion sondern Methode.

C++ kennt etwas, das "Methode" heißt, nicht. Es gibt in der 
Sprachdefinition nur Funktionen.
Im übrigen gibt es unter C++-Programmierern recht unterschiedliche 
Definitionen des Worts "Methode". Daher ist es ganz gut, es zu vermeiden 
und eindeutige Begriffe zu verwenden.

von Oliver (Gast)


Lesenswert?

Marwin schrieb:
> Zeige doch mal einen Fall, wo dieses Feature unverzichtbar ist?

Unverzichtbar ist im Prinzip gar nix. Man kann sogar ganz ohne 
Hochsprache programmieren, alles in Assembler. Muß man aber nicht.

Unverzichtbar ist das Feature in C++ z.B bei den Stream-Ein- und 
Ausgabeoperatoren. Ohne ein vielfach überladenes "<<" wäre das C++-Leben 
schon arg mühsam.

Klassiker sind neben den schon angepsrochenen Konstruktoren auch sowas 
wie Draw-Funktionen mit unterschidlichen Paramterlisten, etc.

Oliver

Karl Heinz Buchegger schrieb:
> Auch in C++ kann man sich wunderbar ins eigene Knie
> schiessen.

Sogar wesentlich eleganter und viel effektiver als in vielen anderen 
Sprachen. Ist leider so.

Oliver

von Zweifel berechtigt (Gast)


Lesenswert?

Marwin schrieb:
> Spaetestens wenn man auch bool und const verwendet, macht der Compiler
> nur noch selten das, was man sich vorestellt...

Der Autor möge mal erklären warum er const hier anführt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.