Hätt ein paar Fragen:
Hab hier eine Library wo Funktionen überladen sind.
Beispielsweise:
1
voidUSB::print(charc)
2
{
3
printByte(c,_uart);
4
}
5
6
voidUSB::print(constcharc[])
7
{
8
printString(c,_uart);
9
}
10
11
voidUSB::print(uint8_tb)
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
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...
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.
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
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.
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.
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.
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
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
voidfoo(inti)
2
{
3
std::cout<<"foo_1"<<std::endl;
4
}
5
6
voidfoo(char*j)
7
{
8
std__cout<<"foo_2"<<std::endl;
9
}
10
11
intmain()
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.
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". :-)
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" ;-)
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?
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.
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.
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.
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.
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.
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.
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
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.