Kilka pytań dotyczących przeciążania funkcji

0

Witam.
Mam pytanie dotyczące podstaw związanych z przeciążaniem funkcji.
Otóż w książce mam coś takiego.

int myFunction (int) - jest prawidłowe (bo to najprostszy przykład więc do tego się nie czepiam)
void myFunction (int) - nieprawidłowe
void myFunction (long) - OK
void myFunction (long, long) - OK
int myFunction (long, long) - nieprawidłowe (tu pewnie chodzi o zakres zmiennej, long jest za duże żeby int go obsłużył)
int myFunction (long, int) - OK
int myFunction (int, long) - OK

I teraz tak. Jak to jest, że funkcja typu void jest zła jeżeli ma parametr int, a dobra jeśli ma parametr long? Przecież i to i to jest typem liczbowym.
I jeżeli int myFunction (long, long) jest nieprawidłowe, to dlaczego int myFunction(long, int) jest poprawne, skoro również tu jest typ long?

dodanie znaczników `` oraz poprawienie tematu wątku - fp

1

Jeśli napiszesz MyFunction((int)5), to z której funkcji korzystasz?
Nie mogą istnieć dwie równorzędne funkcje z taką samą nazwą i taką samą(kolejność!) listą parametrów.

2
adrian.widzew napisał(a):

int myFunction (long, long) - nieprawidłowe (tu pewnie chodzi o zakres zmiennej, long jest za duże żeby int go obsłużył)
Nie, bo wyżej jest void myFunction (long, long) - OK

1

Jak to jest, że funkcja typu void jest zła jeżeli ma parametr int, a dobra jeśli ma parametr long?

Nie parametr tu jest przyczyną, a zwracany typ.

Przeciążane funkcje muszą się różnić czymś więcej, niż zwracanym typem.

Nie możesz mieć jednocześnie

void myFunction (long, long);
int myFunction (long, long);

Bo różnią się tylko zwracanym typem.

0

Przeciążane funkcje muszą różnić się ilością, kolejnością, typem przekazywanych argumentów. Grębosz to bardzo fajnie wyjaśnia. A mianowicie - kompilator podczas kompilacji zmienia sobie nazwy każdej funkcji. I tak np:

int myFunction(long, long) zmienia na (np: ) myFunction_l_l
Zauważ, że nie bierze tu pod uwagę typu zwracanego.

void myFunction(int, long) zmieni na (np: ) myFunction_i_l

Czyli z tego widzisz, że jedynym wyznacznikiem są argumenty. I tak, jak napisał jsrn, gdy przeciążasz funkcje, zastanów się sam, którą byś wybrał Ty, gdybyś był kompilatorem (nie widzisz, co zwraca) ;) A oto prosty przykład, dlaczego nie bierzemy pod uwagę typu zwracanego:

unsigned int myFunction()
int myFunction()

Jeśli teraz będziesz miał wywołanie:

int i = myFunction()

to której użyjesz? To wywołanie jest jak najbardziej prawidłowe (chociaż pewnie niektóre kompilatory mogą się czepiać i ostrzegać). W tym wypadku pomimo, że funkcja zadziała dobrze, możesz dostać złe wyniki, ponieważ przekroczysz zakres inta (jeśli wywołana zostałaby funkcja zwracająca uint). W Delphi po prostu "licznik się przekręci", jak jest w C++ dokładnie, tego nie wiem, ale podejrzewam, że podobnie.

0

kompilator podczas kompilacji zmienia sobie nazwy każdej funkcji

To jest szczegół implementacyjny, równie dobrze mógłby dodawać też typ do nazwy funkcji.
Wszelkie kwestie związane z doborem właściwej funkcji do wykonania też można by teoretycznie rozwiązać (ustalić zasady), ale w tym wypadku powoduje to tyle komplikacji, i tyle zasad trzeba wprowadzać, że po prostu nie warto. Dlatego zdecydowano się na prostą zasadę: nie wolno i już ;-)

1 użytkowników online, w tym zalogowanych: 0, gości: 1