[C++] Problem z polimorfizmem nazw funkcji


(MichałT) #1

Witajcie!

Mam straaaaszny problem. Polega on (to zabawne ale tak jest niestety) na tym że chyba kompilator przepuszcza mi kardynalny błąd ale... program działa i to świetnie. O.O

Chodzi o polimorfizm nazw funkcji. Zasada jest podobno taka, że jeśli stosujemy tą samą nazwę funkcji, musi ona być tego samego typu - tak przynajmniej pisali w moim podręczniku... Niedawno sobie przypomniałem że biblioteczka którą piszę nie powinna wcale działać! Jedna funkcja jest typu wskaźnikowego a druga void.

Przykład:

int* ciasto(int kotlet)

{

 kotlet >> mniammniam;

return adresdokuchni;

}


void ciasto(char truskawka)

{

 mniam(truskawka + śmietana); 

}

Teoretycznie, tego typu konstrukcja nie powinna działać a... działa!

Kompiluję dla pewności z flagami -std=c++98 -Wextra -pedantic i jest ok! Zero ostrzeżeń i błędów.

O co kaman! Najzabawniejsze jest to, że kompilator poprawia standard :smiley:

Kompilator GCC wersja 4.7 - kompilowane na Debianie Wheezy.


(Fiołek) #2

To nie jest polimorfizm, to jest przeciążanie funkcji. :wink:

W C++ może istnieć wiele funkcji o takiej samej nazwie, ale muszą się dać jednoznacznie zidentyfikować przez parametry. Tutaj obie funkcje przyjmują różne parametry, więc wszystko jest prawidłowo.

Polimorfizm jest wtedy, gdy klasa posiada funkcje wirtualne, a klasa dziedzicząca je nadpisuje.


([alex]) #3

Po pierwsze nie ma czegoś takiego jak polimorfizm funkcji, polimorfizm dotyczy klas i tylko klas.

Funkcji o identycznych nazwach nazywają przeładowaniem funkcji.

Muszą się różnić ilością parametrów lub typami parametrów.

Wartość zwracana może być dowolna.

Co do podręcznika - wywalić i po sprawie.


(Sawyer47) #4

Forma polimorfizmu, której przykład zamieściłeś nazywa się przeciążaniem funkcji (function overloading) - można mieć wiele funkcji o tej samej nazwie przyjmujące różne parametry - więc jest to sytuacja zupełnie odwrotna niż " że jeśli stosujemy tą samą nazwę funkcji, musi ona być tego samego typu". Nie miałoby to sensu, nie można mieć dwóch funkcji o takich samych nazwach i parametrach.

Natomiast polimorfizm oparty na metodach w klasach i dziedziczeniu (subtype polymorphism) wymaga aby typy metod były takie same (z pewnymi wyjątkami) - jednak metody te istnieją w różnych klasach. Wspomniany przez Ciebie fragment książki być może opisuje właśnie tę sytuację.


(MichałT) #5

Dzięki za odpowiedź! Co do podręcznika... tam serio autor to nazywa polimorfizmem...

cytat:

Przykłady:

i dalej...

Co ciekawe, gdy spróbowałem przenieść kod do ANSI C to kompilator przyczepił się do konfliktów...

...ale ANSI C w ogóle nie obsługuje tego typu zjawiska chyba...

Odpaliłem kod w DevC++ przez wine i też się doczepiło do konfliktów... ale doczepiło się też do "::" w std::cout więc to może być wina odpalania w wine...

nr47 Książka opisuje zjawiska zachodzące w przestrzeni globalnej. Chodzi o zwykłe funkcje.

Edit:

Wygląda to tak (fragment):

#include 


// (...) 


int* divfract(int num1, int den1, int num2, int den2)

{

	int div_num;

	int div_den;


	if (num1 != num2 && den1 == den2)

	{

	 div_num = num1/num2;

	 div_den = den1;

	 _CFMEM(div_num, div_den);

	}

	else if (num1 == num2 && den1 == den2) 

	{

	  _CFMEM(1,1);

	}

	else if (num1 == 0 || num2 == 0 || den1 == 0 || den2 == 0) 

	{

	  std::cout << "[WARNING!]: Division by zero!\n";

	  _CFMEM(0,1);

	}

	else

	{

	  div_num = (num1 * den2) / (num2 * den1);

	  div_den = den1 * den2;

	  _CFMEM(div_num, div_den);

	}

	return _CFADR;

}


void divfract(int* fract, int* fract2)

{

 if (fract[1] > 0 && fract2[1] >0) divfract(*fract, fract[1], *fract2, fract2[1]);

}


[/code]

edit:

W sumie nic w tym przypadku nie stoi na przeszkodzie aby funkcję void przerobić na int*...

...ale w innych programach w przyszłości może już nie być tak lekko... ;/ Dlatego wolałbym wiedzieć co jest grane...


([alex]) #6

No to czytanie ze zrozumieniem się kłania.

muszą różnić się: - "liczbą argumentów i lub ich typami"

nie można: - "różniących się jedynie typem wartości".

Przeciążenie funkcji pojawiło się dopiero w C++.

Funkcje divfract różnią się ilością oraz typami parametrów nie różnią się jedynie typem wartości.


(MichałT) #7

[alex],

aha...

Czyli:

...jest źle ale...

jest ok tak? Wybacz, ale z książki to jasno nie wynika... Gdyby był jeszcze przykład, byłoby jaśniej :stuck_out_tongue_winking_eye:


([alex]) #8

Dokładnie tak. Z tego fragmentu co podałeś dokładnie tak i absolutnie jednoznacznie to wynika.


(MichałT) #9

Niech będzie... Ja to po prostu źle ogarnąłem i najzabawniejsze jest to, że mimo źle nabytej wiedzy, kod i tak jest poprawny. :lol:

Zabawnie będzie przenosić tą biblioteczkę na ansi... Pewnie jeszcze więcej wskaźników... -,-

Dzięki za pomoc i odpowiedzi!


(Rolek0) #10

@_MichałT_ Polecam http://www.intercon.pl/~sektor/cbx/. Warto też poczytać http://gynvael.coldwind.pl/?id=238 oraz http://xion.org.pl/productions/texts/coding/megatutorial/. Have fun :wink: