Podstawy informatyki 2013/2014 Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.

1 Podstawy informatyki 2013/2014 Łukasz Sztangret Katedra...
Author: Rafał Milczanowski
0 downloads 2 Views

1 Podstawy informatyki 2013/2014 Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego Matuszyka

2 Przeładownie nazwy funkcji polega na tym, że w danym zakresie ważności jest więcej niż jedna funkcja o takiej samej nazwie. To, która z nich zostaje w danym przypadku uaktywniona, zależy od liczby i typu argumentów wywołania jej. 1 1 Grębosz J., Symfonia C++ standard

3 Wybór funkcji do przeładowania Warto rozważyć przeładowanie deklaracji funkcji gdy: –funkcje posiadają pewną cechę wspólną a mają działać na obiektach różnych typów int wypiszWynik( const jakas_klasa & A); int wypiszWynik( const double A[], unsigned int size); –funkcje w sensie abstrakcyjnym wykonują analogiczną czynność, która w języku naturalnym ma tę samą nazwę double potega( double x, double y); int potega( int x, int y); I odwrotnie: nie przeładowywać deklaracji, jeśli nie potrzebujemy tej samej nazwy dla różnych działań

4 Lista argumentów przy przeładowaniu Dwie funkcje mają różną listę argumentów gdy: Funkcje posiadają różną liczbę argumentów Funkcje posiadają różne typy argumentów (na tych samych pozycjach) Funkcje posiadają różną kolejność argumentów Typ zwracany przez przeładowaną funkcję nie jest brany pod uwagę! Definicje funkcji o takiej samej nazwie i które nie spełniają powyższych wymagań są wzajemnie niejednoznaczne

5 Różna liczba argumentów #include using namespace std; void napis(int a){cout

6 Różne typy argumentów #include using namespace std; void napis(int a){cout

7 Różna kolejność argumentów #include using namespace std; void napis(int a, double b){cout

8 Różne typy funkcji #include using namespace std; int zwroc(double a){return static_cast (a);} double zwroc(double a){return a;} int main() { int a=zwroc(1.5); double b=zwroc(1.5); return 0; } BŁĄD – funkcje nierozróżnialne cout

9 Argumenty domniemane #include using namespace std; void napis(int a){cout

10 typedef #include using namespace std; typedef int calkowity; void napis(int a){cout

11 enum #include using namespace std; enum litera {a=1,b,c,d}; void napis(int a){cout

12 Tablica i wskaźnik #include using namespace std; void napis(int a[]){cout

13 Tablice wielowymiarowe #include using namespace std; void napis(int a[2][3]){cout

14 Tablice wielowymiarowe #include using namespace std; void napis(int a[2][3]){cout

15 Referencja #include using namespace std; void napis(int a){cout

16 Typy: T, const T, volatile T #include using namespace std; void napis(int a){cout

17 Typy: T*, const T*, volatile T* #include using namespace std; void napis(int *a){cout

18 Typy: T&, const T&, volatile T& #include using namespace std; void napis(int &a){cout

19 Wskaźnik do przeładowanej funkcji #include using namespace std; void napis(int a){cout

20 Wskaźnik do przeładowanej funkcji #include using namespace std; void napis(int a){cout

21 Konwersje przy dopasowaniu Kompilator dopasowując deklarację funkcji może przeprowadzić konwersje argumentów Dla każdego argumentu może zostać przeprowadzona oddzielna ścieżka konwersji, o określonej jakości Rozważana w dopasowaniu funkcja F1 jest lepsza od innej rozważanej funkcji F2 jeżeli: –Ścieżka konwersji F1 dla każdego argumentu jest nie gorsza niż ścieżka dla F2 ORAZ –Dla co najmniej jednego argumentu ścieżka konwersji jest lepsza dla F1 Ogólnie jakość konwersji zależy od stopnia jej skomplikowania oraz stratności

22 Etapy dopasowania 1.Dopasowanie dokładne –dopasowanie dokładne z trywialną konwersją 2.Dopasowanie na zasadzie awansowania 3.Dopasowanie z użyciem konwersji standardowych 4.Dopasowanie z użyciem konwersji zdefiniowanych przez użytkownika 5.Dopasowanie do funkcji z wielokropkiem

23 Konwersje przy dopasowaniu 1.Dopasowanie dosłowne Dopasowanie dosłowne z trywialną konwersją int [] -> int* 2.Dopasowanie z awansem float -> double char signed char unsigned char-> int -> unsigned int short int unsigned short int

24 Konwersje przy dopasowaniu 2.Dopasowanie z awansem c.d. bool -> int wchar_t enum-> int -> unsigned int -> long -> unsigned long 3.Dopasowanie za pomocą konwersji standartowych 1.typu całkowitego int -> unsigned int unsigned int -> int

25 Konwersje przy dopasowaniu 3.Dopasowanie za pomocą konwersji standartowych c.d. 2.typu zmiennoprzecinkowego double -> float float -> double 3.pomiędzy typem całkowitym a zmiennoprzecinkowym zmiennoprzecinkowy -> całkowity całkowity -> zmiennoprzecinkowy 5.wskaźników dowolny wskaźnik nie-const i nie-volatile -> void* wsk. do klasy pochodnej -> wsk. do klasy podstawowej 6.referencji ref. do klasy pochodnej -> ref. do klasy podstawowej

26 Konwersje przy dopasowaniu 4.Dopasowanie za pomocą konwersji definiowanych przez użytkownika 5.Dopasowanie do funkcji z wielokropkiem void f(int a){cout

27 Konwersje wskaźników Konwersje wskaźników nie zachodzą! 1.int* -> double* - przykład z poprzedniego wykładu 2.int* -> int [] – tablica zna swój rozmiar, wskaźnik nie wie czy pokazuje na pojedynczy element, czy na tablicę 3.wskaźnik pokazujący na funkcję wywoływaną z argumentem typu int nie może pokazywać na funkcję wywoływaną z parametrem typu char UWAGA! Nawet typ zwracany jest tutaj istotny!

28 Przykłady konwersji void fun(double a){cout

29 Przykłady konwersji void f(int a){cout

30 Przykłady konwersji void fun(double a){cout

31 Przykłady konwersji void fun(double a){cout

32 Konwersje kilku argumentów #include using namespace std; void f(double a, int b){cout

33 Funkcja zwracająca większą wartość int wieksza(int a,int b) { return (a > b) ? a : b; } int main() { int a,b; a=5; b=2; cout

34 ctrl+c, ctrl+v int wieksza(int a,int b) { return (a > b) ? a : b; } double wieksza(double a,double b) { return (a > b) ? a : b; } int main() { int a,b; a=5; b=2; cout

35 Szablon funkcji template typ wieksza(typ a, typ b) { return (a > b) ? a : b; } int main() { int a,b; a=5; b=2; cout

36 Funkcje szablonowe Kompilator generuje funkcję szablonową gdy: wywołujemy funkcję, odwołujemy się do jej adresu. Funkcja szablonowa z jednym zestawem parametrów generowana jest tylko raz. Podobnie jak w przypadku przeładowań nazw funkcji typ rezultatu funkcji się nie liczy.

37 Kilka przykładów template typ1 wieksza(typ1 a, typ2 b, typ1 c) {…} template typ wieksza(typ a, typ *b) {…} template typ wieksza(typ a, int b) {…} template typ_w wieksza(typ1 a, typ2 b, typ1 c, typ_w) {...}

38 Problemy z typami definiowanymi template typ wieksza(typ a, typ b) { return (a > b) ? a : b; } class zespolona { public: double re,im; }; int main() { zespolona A,B; A.re=5; A.im=2; B.re=1; B.im=3; cout

39 Problemy z typami wbudowanymi template double funkcja(typ a) { double m=a.modul(); return m; } class zespolona { public: double re,im; double modul(){ return sqrt(re*re+im*im);} }; int main() { zespolona A; A.re=5; A.im=2; cout

40 Funkcja specjalizowana template typ wieksza(typ a, typ b) { cout

41 Kolejność argumentów funkcji template typ1 wieksza(typ1 a, typ2 b) { return (a > b) ? a : b; } int main() { double a=3.5; int b=2; cout

42 Konflikt template typ1 wieksza(typ1 a, typ2 b) { return (a > b) ? a : b; } template typ2 wieksza(typ1 a, typ2 b) { return (a > b) ? a : b; } Szablony różnią się tylko typem zwracanym

43 Obiekty lokalne typu typ template typ dzialanie(typ a, typ b) { typ w; w=3*a+b; return w; } int main() { int a=3; int b=2; cout

44 Typy pochodne template void zmiana(typ &a, typ &b) { typ c=a; a=b; b=c; } int main() { int a=3; int b=2; cout

45 Typy pochodne template void zmiana(typ &a, typ &b) { typ c=a; a=b; b=c; } int main() { char *a="AAA"; char *b="BBB"; cout

46 Szablon generujący funkcje inline template inline typ wieksza(typ a, typ b) { return (a > b) ? a : b; }

47 Obiekty lokalne statyczne template void funkcja(typ a) { static int licznik=0; licznik++; cout

48 Run-Time Type Identyfication #include using namespace std; template void funkcja(typ a) { cout

49 Prezentacja udostępniona na licencji Creative Commons: Uznanie autorstwa, Na tych samych warunkach 3.0. Pewne prawa zastrzeżone na rzecz autorów. Zezwala się na dowolne wykorzystywanie treści pod warunkiem wskazania autorów jako właścicieli praw do prezentacji oraz zachowania niniejszej informacji licencyjnej tak długo, jak tylko na utwory zależne będzie udzielana taka sama licencja. Tekst licencji dostępny jest na stronie: http://creativecommons.org/licenses/by-sa/3.0/deed.pl