12:00Temat wykladu:
C++: Szablony i wyjątki (by MeMeK, 17.08.06) @ wyklady.net
Komentarze: http://forum.wyklady.net/index.php?75.0
12:05MeMeKwitam was na moim kolejnym wykladzie
MeMeKdzisiaj porozmawiamy sobie o
MeMeK1. szablonach
MeMeK2. wyjatkach
MeMeKw c++ ofkz ;>
MeMeKpo zakonczeniu wykladu bedzie mozna go skomentowac
MeMeKhttp://forum.wyklady.net/index.php?75.0
MeMeKo tutaj
12:06MeMeKkk zaczynajmy
MeMeKwszyscy wiemy jaki jest c++
MeMeKmamy np taka sobie funkcje...
MeMeKhttp://memek.piwko.pl/wyklad_sz/przyklad1.cpp
MeMeKpopatrzmy
MeMeK
Suma a i b wynosi 12
12:07MeMeKno fajnie
MeMeKdziala tak jak powinno
MeMeKale nasza funkcja dodaj (wiem ze troche trywialne)
MeMeKprzeciez moglaby dzialac tez dla innych zmiennych niz int
MeMeKnp dla double
12:08MeMeKale kompilator by nas ostrzegl ze kompinujemy gdybysmy do funkci przeslali double
MeMeKchociaz tak naprawde on i tak prz przekazywaniu argumentow do funkcji
MeMeKprzekazuje je jako double
12:09MeMeKale k
MeMeKzrobimy jak powinno byc
MeMeKhttp://memek.piwko.pl/wyklad_sz/przyklad2.cpp
MeMeKuzylem generatora liczb losowych
MeMeKzeby nie wymyslac za duzo
MeMeKi zeby bylo ciekawiej
MeMeK;>
12:10MeMeKdla dociekliwych
MeMeKhttp://www.cplusplus.com/ref/cstdlib/srand.html
MeMeKi teraz
MeMeK
Suma a i b wynosi 576
MeMeK
Suma c i d wynosi 149
MeMeK
Suma e i f wynosi 921
MeMeK
Suma g i h wynosi 413
MeMeKladnie dziala dla roznych typow
MeMeKale w koncu to sa 4 rozne funkcje
12:11MeMeKtroche nam sie nie usmiecha pisac po kilka wersci tej samej funkcji
MeMeKtylko z roznica typow
MeMeKc++ to bardzo rygorystyczny jezyk pod wzgledem sprawdzania typow danych
MeMeKale jakze piekny ;.
12:12MeMeKwidac ze mozna zrobic taki wzorzec tej funkcji
MeMeKwygladalby on mniej wiecej tak:
MeMeKTYP dodaj (TYP a, TYP b)
MeMeK{
MeMeKreturn a+b;
MeMeK}
12:13MeMeKwszystkie 4 funkcje w poprzednim przykladzieoperaly sie o ten wzorzecx
MeMeKokazuje sie ze w c++ mozna cos takiego zastosowac ;>
MeMeKto bardzo by nam pomoglo ;]
MeMeKale jak ?
MeMeKhmmm..
12:14MeMeKnasz wzorzec
MeMeKczyli szablon
MeMeKang template
MeMeKw implementacji c++ wyglada o tak
MeMeKtemplate <typename TYP> TYP dodaj (TYP a, TYP b)
MeMeK{
MeMeKreturn a+b;
MeMeK}
12:15MeMeKto jest oczywiscie szablon naszej funkcji dodaj
MeMeKz poprzedniego przykladu
MeMeKszablony powinno sie oddzielac od reszty kodu
MeMeKwstawiajac je do plikow naglowkowych *.h
12:16MeMeKczy tam *.hpp (zalezy od ide)
MeMeKwiec jak to jest zrobione
MeMeKtemplate <parametry>
12:17MeMeKnajpierw spojrzmy na przykad
MeMeKhttp://memek.piwko.pl/wyklad_sz/przyklad3.cpp
MeMeKhuh ;]
MeMeKo polowe mniej kodu
MeMeKa efekt taki sam
MeMeK
Suma a i b wynosi 705
MeMeK
Suma c i d wynosi 256
MeMeK
Suma e i f wynosi 95
MeMeK
Suma g i h wynosi 593
MeMeK(nie bede dawal do osobnych plikoow w przykladach) ale wy tak robcie ;>
12:18MeMeKwystarczy napisac jedna funkcje zamiast 4
MeMeKekstra
MeMeKwszystko dzieki mechanizmowi szablonow
12:19MeMeKjednak musimy pamietac
MeMeKze nie wiemy na jakich typach bedziemy w tej funkcji dzialac
MeMeKmoze to byc wszystko
MeMeKnawet nasza wlasna klasa
12:20MeMeKlooknijmy np tu
MeMeKhttp://memek.piwko.pl/wyklad_sz/przyklad4.cpp
MeMeKmamy tam linijke
MeMeKreturn (a >= 0 ? "dodatnia" : "ujemna");
MeMeKwidac ze porownujemy nasz szablonowy parametr z zerem
12:21MeMeKale takie 0 doslowne jest typu int
MeMeKwiec kompilator moze nas ostrzec ze porownujemy rozne typy
MeMeKtroche to naciagane
12:22MeMeKjak tu miec zero takiego typu jak argument
MeMeKwiemy ze np wywolanie takie
MeMeKint()
MeMeKzwraca nam 0 typu int
MeMeKa double()
MeMeKzwraca 0 typu double
MeMeKwiec czemu nie zasosujemy typu szablonowego wewnatrz ciala funkcji
12:23MeMeKa nbie tylko w parametrach
MeMeKto sie robi bardzo prosto
MeMeKwystarczy wywolac nam TYP()
12:24MeMeKw koncu TYP bedzie sie zmienail w zaleznosci od tego co zostanie wyslane jako argument
MeMeKpo porawieniu w wyniku za wiwl sie nie zmieni
12:25MeMeKnadal dostaniemy kilka liczb losowych
MeMeK
Liczba a (-447) jest ujemna
MeMeK
Liczba b (-234) jest ujemna
MeMeK
Liczba c (128) jest dodatnia
MeMeK
Liczba d (-6) jest ujemna
MeMeKteraz zero bedzie zawsze 0 odpowiedniego typu
MeMeK0f
MeMeK0u
MeMeKfalse
MeMeKitp
12:26MeMeKa co jesli mamy funkcje ktora moze miec 2 rozne parametry
MeMeKhm
MeMeKtemplate <typename TYP, typename TYP2> string spr (TYP a, TYP2 b)
MeMeK{
MeMeK/ jakies operacje na zmiennych ktore moga byc 2och roznych typow (a moga byc takie same)
MeMeK}
MeMeKrownie dobrze mozemy dodac kilka argumentow do szablony
MeMeKszablonu*
12:27MeMeKi spokojnie go uzywac jak zawsze
MeMeKale ok
MeMeKprzeciez mozemy wyslac do naszej funkcji szablonowej jakas naszej klase
MeMeKa ona nie zawsze umie sie porownywac czy dodawac (czyt nie ma przeladowanego opertaora)
12:28MeMeKjak powiedziec szablonowi ze moga byc wyjatki od reguly
MeMeKktora wlasnie ustanowilismy
12:29MeMeKano mozemy zrobic odpowiednia specjalizacje naszej funkcji szablonowej
MeMeKjak ma sie zachowac gdy dostani taki a taki argument
MeMeKrobimy to tak
MeMeKtemplate<> string spr (specjalny_typ a)
MeMeK{
MeMeK/inne operacje niz zwykle
MeMeK}
MeMeKczyli normalna funkcja dla jakiegos typu
12:30MeMeKpoprzedzona
MeMeKtemplate <>
MeMeKjak widac do template nie podajemy wtedy argumentow
MeMeKteraz nasza funkcja sie odpowiednio zachowa w specjalnych sytuacjach
12:31MeMeKmalo tego
MeMeKmozemy zrobic specjalna oblsuge
MeMeKdla calej grupy wyjatkow
MeMeKrobimy to o tak
MeMeKtemplate <typename TYP> string spr<TYP*> (TYP* wsk)
MeMeK{
MeMeK/ juz na wzkazniku
MeMeK}
12:32MeMeKczyli mamy operacje na wskazniku
MeMeKa one moga sie roznic od operacji na normalnych obiektach
MeMeKjak takie cos wywolac w kodzie
MeMeKano wlasnie tak
MeMeK*(spr(jakis_wzkaznik));
12:33MeMeKprosto i przejrzyscie ;>
MeMeKno to teraz mamy nasza funkcje szablonowa
MeMeKi bedzie wywolywana niejawnie jej odpowiednia specjalizacja
MeMeKale mozemy tez wywolac ja jawnie
MeMeKo tak
MeMeKspr<int>(a,b);
12:34MeMeKdo nazwy funkcji w nawiasach ostrych piszemy typ
MeMeKa jak to wyglada w skompilowanym pliku
MeMeKczy to jakas heurystyka
MeMeKniee
12:35MeMeKkompilator juz na etapie kompilacji sprawdza dla jakich typow jest wywolywana nasza
MeMeKfunkcja szablonowa
MeMeKi tworzy odpowiednia ilosc jej specjalizacji
MeMeKa nie wszystkie mozliwe jak mogloby sie wydawac
12:36MeMeKtu kompilator zachowuje sie sprytnie ;>
MeMeKa co ze wzkaznikami na funkcje
MeMeKjak pokazac na taka funkcje szablonowa
MeMeKotoz na szablon nie da sie pokazac
MeMeKbo to nie jest przeciez funkcja tak na prawde
MeMeKtylko instrukcje dla kompilatora
12:37MeMeKon dopiero wygeneruje funkcje
MeMeKwiec nie da sie?
MeMeKoczywiscie ze sie da
MeMeKtylko musimy pokazywac na konretna specjalizacje funkcji szablonowej
12:38MeMeKok
MeMeKteraz troche o szablonach klas
MeMeKbo co jesli mamy np prosta klase
MeMeKktora zawiera opis i liczbe
12:39MeMeKhmm
MeMeKprzeciez liczba to moze byc integer
MeMeKdouble
MeMeKfloat
MeMeKczy inne ustrojtwo
MeMeK;>
MeMeKokazuje sie ze da sie stworzyc taka klase szablonowa
12:40MeMeKhttp://memek.piwko.pl/wyklad_sz/przyklad6.cpp
MeMeKwidzimy
MeMeKtemplate <typename TYP> class liczbaA
MeMeK{
MeMeKpublic:
MeMeKTYP liczba;
MeMeKstring opis;
MeMeK};
MeMeKbardzo podobne do szablonu klasy
12:41MeMeKtfu
MeMeKfunkcji
MeMeK;>
MeMeKtez posiada slowko template
MeMeKz argumentami w ostrych nawiasach
MeMeKa wewnatrz klasy uzywamy odpowiedni typ slowkiem TYP
12:42MeMeKbo taki wybralismy w nawiasach ostrych <>
MeMeKwiec ogolna budowa szablonow kloas
MeMeKtemplate <tyoename TYP> class klasa {/*cos*/};
MeMeKa co z dziedziczeniem takiej klasy
12:43MeMeKjak to zrobic
MeMeKano musimy dziedziczyc nie z szablonu
MeMeKale z konkretnej specalizacji
MeMeKclass dziecko : public liczbaA<int> {};
12:44MeMeKno to wiemy juz dosc duzo
MeMeKaa a przyjazn
MeMeKczy to wyglada juz prosto
MeMeKtemplate <typename INNY> friend class klasa<INNY>;
MeMeKtak sie przyjaznimy z klasa szablonowa
MeMeKktora ma argument szablony INNY
12:45MeMeKok a jak zrobic szablon funkcji skladowej klasy
MeMeKtaki wyjdzie nam szablon w szablonie
MeMeKtemplate <typename TYP_Z_KLASY>
MeMeKtemplate <typename TYP_FUNKCJI>
MeMeKtyp_zwracany klasa<TYP_Z_KLASY>::funk (TYP_Z_FUNKCJI a)
MeMeK{
MeMeK/
MeMeK}
MeMeKtroche to skompikowane
12:46MeMeKale da sie przyzwyczaic
MeMeK;>
MeMeKa co jesli mamy w szablonach klas wyjatki
MeMeKtrzeba zrobic specjalizacje szablonu klas
MeMeKrobimy to podobnie jak przy funkcjach
MeMeKtemplate <> class klasa<char> {};
12:47MeMeKpo nazwie klasy w ostrych nawiasach dajemy typ dla jakiego specjalizujemy
MeMeKnasza klase
MeMeKi zostala nam specjalizacja funkcji skladowej klasy
MeMeKtez to jest w miare latwe
MeMeKspoecjal fun
MeMeKtemplate <> klasa<char*>::funk () {}
12:48MeMeKzadanie dla chetnych ;>
MeMeKnapiszcie program w ktorym wykorzystacie wszystko o czym powiedzialem o szablonach
12:49MeMeKdobra przechodzimy dalej
MeMeKWYJATKI
MeMeKpomyslmy sobie ze mamy jakis program
12:50MeMeKgdzies w nim wywolujemy funkcje
MeMeKi chcemy miec oblsuge bledow
MeMeKnp funkcja do obliczania odwrotnosci
MeMeKdajemy jej -5
MeMeKto ona zwraca -0,2
12:51MeMeKczyli zwraca 1/argument
MeMeKok jaki moze tu byc blad
MeMeKno nie mozemy dzielic przez 0
MeMeKwiec gdybysamy dostali 0
MeMeKto trzeba o tym jakos powiedziec
12:52MeMeKo tym bledzie
MeMeKale jak
MeMeKno mozna zwrocic jakis nietypowy wynikl
MeMeKale jaki tu moze byc nietypowy wynik
MeMeKmamy tylko jedna wolna opcje
MeMeK0
MeMeKwiec gdy funkcja zwroci 0 znaczy ze cos poszlo nie tak
12:53MeMeKkonkretnie blad dzielenia
MeMeKno to mamy obsluzony blad
MeMeKok a co jesli nie ma jakiejs wolnej wartosci
MeMeKtzn funkcja moze zwrocic kazda mozliwa liczbe
MeMeKjak powiedziec o bledzie
12:54MeMeKnp w funkcji do obliczania tangensa
12:55MeMeKprzeciez nie istnieje tangens
MeMeKnp z 90 stopni
MeMeKjak o tym powiedziec
MeMeKi tu przydaje sie mechanizm wyjatkow
12:56MeMeKw mechanizmie wyjatkow sa 3 wazne slowa
MeMeKtry
MeMeKthrow
MeMeKcatch
MeMeKwiec jak mozemy zrobic oblsuge takiego wyjatku
MeMeKtry
MeMeK{
MeMeK/niebezpieczne instrukcje
MeMeK/ gdzie tu rzycamy (throw) wyjatek
MeMeK}
MeMeKcatch (arg)
MeMeK{
MeMeK/ obsluga wyjatku
MeMeK}
12:57MeMeKjak widac niebezpieczne instrukcje (takie ktore moga sie nie powiesc)
MeMeKumieszczamy w bloku tr {}
MeMeKtry {}
MeMeKi gdzies tam sa np wywolania funkcji
MeMeKi inne operacje
MeMeKi jesli nam cos nie pasuje
12:58MeMeKto rzucamy wyjatek
MeMeKza pomoca instrukcji throw
MeMeKthrow obiekt;
MeMeKrzucic mozna kazdym obiektem
MeMeKint'em double'm
MeMeKjakas nasza klasa
12:59MeMeKmoze byc tez tak
MeMeKthrow 78f;
MeMeKthrow 78.0f;
MeMeKmoj blad
MeMeKwiec taki rzucony wyjatej leci
MeMeKdopiki nie napotka catch
MeMeKczyli dopokie nie zostanie zlapany
13:00MeMeKcatch (typ)
MeMeK{
MeMeK/obsluga
MeMeK}
MeMeKa to co za "typ" ?
MeMeKano przeciez mozemy rzucac dowolnym obiektem
MeMeKwiec trzeba zlapac obiekt takiego typu jakiego rzucilismy
13:01MeMeKbloki try-catch
MeMeKmoga byc zagniezdzone
MeMeKcos jak if else
13:02MeMeKi jesli gdzies zostanie rzucony wyjatek
MeMeKto najpierw doleci do odpowiadajacego mu bloku catch
MeMeKrownie dobrze moze byc jeden blok try
MeMeKa kilka blokow catch
MeMeKw zaleznosci od typu
MeMeKrzuconego obiektu
13:03MeMeKwtedy stosujemy tzw sito
MeMeKczyli np mamy mozliwe do wyrzucenia 4 typy
MeMeKwyjatkow
MeMeKbool
MeMeKchar
MeMeKint
MeMeKdouble
MeMeKjak wiem
MeMeKbool<char<int<double
13:04MeMeKzajmuja w pamieci
MeMeK1bit<8bitow<32bity<64bity
MeMeKwiec powiedzmy ze mamy tak ustawione bloki catch
MeMeKcatch (double) {}
13:05MeMeKcatch (int) {}
MeMeKcatch (char) []
MeMeKcatch (bool) {}
MeMeKi teraz leci sobie taki wyjatek
MeMeKi najpier dolatuje do catch (double)
13:06MeMeKa wyjatkiem jest obiekt char
MeMeKi coi sie dzieje
MeMeKchar wpadnie do catch (double)
MeMeKdlatego ze jest mniejszy niz double
MeMeKprzeleci przez sito
13:07MeMeKwiec moze poustawiajmy lepiej nase bloki
MeMeKod najdrobniejszego sita
MeMeKdo najgrubdzego
MeMeKcatch (bool) {}
MeMeKcatch (char) {}
MeMeKcatch (int) {}
MeMeKcatch (double) {}
13:08MeMeKteraz jest ok
MeMeKco jest za duze do boola leci dalej
MeMeKa co jesli bedzie wiksze od double
MeMeK(np jakas nasza klasa)
MeMeKwtedy mozna go zlapac tak
MeMeKcatch (...)
MeMeK{
MeMeK/instrukcje
MeMeK}
13:09MeMeKjako argument dajemy trzy kropki
MeMeK(...)
MeMeKi tu wpadna wszystkie wyjatki
MeMeKmozemy tez przekazac wyjatek dalej w bloku catch
MeMeKrobimy to pojedyncza instrukcja
MeMeKthrow;
13:10MeMeKjest pewnien interesujacy efekt zwiazany z "lotem" wyjatku
MeMeKjest nim odwijanie stosu]
MeMeKpowiedzmy sobie ze taki wyjatek zostal rzucony gdzies w gleboko zagniezdzonym miejscu
13:11MeMeKpowiedzmy ze w czasie rekurencji
MeMeKi on tak bedzie "lecial" dopokie nie napotka dobrago catch
MeMeKa jesli nie napotka
MeMeKto bedzie dzialaj jak break i return w jednym
13:12MeMeKbedzie konczyl wszystkie funkcje
MeMeKpetle
MeMeKbloki
MeMeKobiekty lokalne (automatyczne)
MeMeKbeda niszczone
13:13MeMeKale o tym powiem za moment
MeMeKjak sie przed takim czyms ustrzec
MeMeKmusimy wiedziec jaki typ wyjatku moze rzucic nam np funkcja
13:14MeMeKmozna to ladnie zapisac w jej deklaracji
MeMeKo tak
MeMeKtyp_zwrotu nazwa(argumenty) throw(typ_wyjatku);
MeMeKtak zadeklarowana funkcja mowi nam ze MOZE rzucic wyjatek
MeMeKa my musimy sie juz nim zajac
MeMeKgdy np ktos bedzie uzywal naszych funkcji
13:15MeMeKto wtedy to jest bardzo dobre rozwiazanie
MeMeKdobra wracajac do odwijania stosu
MeMeKwiec taki nieobsluzony wyjatek
MeMeKmoze nam niemile zakonczyc program
MeMeKjak temu zapobiedz
13:16MeMeKano mozna ustawic sobie specjalna funkcje
MeMeKunexpected()
MeMeKktora zajmie sie nieobsuzonymi wyjatkami
MeMeKzazwyczaj wypisuje sie jakis alert
MeMeKi konczy program
13:17MeMeKale nie stworzymy takiej funkcji normalnie
MeMeKjak kazdej innej
MeMeKtrzeba sie troche pogimnastykowac
MeMeKustawiamy ja za pomoca innej funkcji
MeMeKdzieki set_unexpected();
MeMeKjej deklaracja wyglada tak
MeMeKunexpected_handler set_unexpected(unexpected_handler pfnFunction);
13:18MeMeKwidac ze do argumentu dajemy jej wskaznik na nowa funkcje obslugi nieobsluzonych wyjatkow
MeMeKjednak gdybysmy nie zrobili takiej naszej funkcji
13:19MeMeKto defaultowa wywola defaultowa funkcje terminate
MeMeKktora to wywola funkcje abort
MeMeKco sie zakonczy nagla smiercia naszego programu
MeMeKmozemy ustawic swoja wlasna funkcje terminate
MeMeKteraz was zaskocze
MeMeKza pomoca
13:20MeMeKterminate_handler set_terminate(terminate_handler pfnFunction);
MeMeKczyli dokladnie tak samo
MeMeKpodaja c jej adres nowej funkcji
MeMeKwewnatrz takiej funkcji pasowalu by dac instrukcje
MeMeKexit (1);
MeMeKczyli ze cos w programie poszlo nie tak
13:21MeMeKpnalezy pamietac ze podczas "lotu" jednego wyjatku nie mozna rzucac drugiego
MeMeKpewnie sie dziwicie jak?
13:22MeMeKano sa az 2 miejsca gdzie mozna rzucic wyjatek w czasie lotu innego
MeMeKkonstruktor i destruktor
MeMeKdestruktor dlatego ze podczas odwijania stosu przy wychodzeniu z bloku
MeMeKwywolywane sa destruktory obiektow
MeMeKa konstruktor dlatego
MeMeKdodam konstruktor kopiujacy
13:23MeMeKze podczas lapania wyjatku przez catch
MeMeKjest on niejawne wywolywany
MeMeKok
MeMeKjest jeden powazny problem z tym odwijaniem stosu
MeMeKjesli gdzie w bloku try
13:24MeMeKalokujemy kawalek pamieci
MeMeKoperatorem new
MeMeKto po rzuceniu wyjatku
MeMeKpozostale instrukcje sa pomijane
MeMeKlaczne
MeMeKz
MeMeKdelete
MeMeKmamy wyciek pamieci
MeMeKmemory leak
MeMeKjak temu zaradzic
13:25MeMeKjest sposob
MeMeKwiemy ze destruktory sa wywolywane
MeMeKwiec mozna stworzyc sobie taki madry wskaznik
MeMeKktory w destruktorze bedzie zwalnial pamiec
MeMeKdelete
MeMeKale nie rozpedzajmy sie tak
13:26MeMeKjest juz taka klasa
MeMeKnazywa sie auto_ptr
MeMeKjak sie pewnie domyslacie jest do szablon klas
MeMeKwiec moze dzialac nawet na naszych nowopowstalych obiektach
13:27MeMeKpamietajmy ze nalezy dodac naglowek
MeMeK#include <memory>
MeMeKuzywamy go tak
MeMeKauto_ptr<nasza_klasa> wskaznik (new nasza_klasa);
MeMeKi juz pozamiatane
13:28MeMeKna koniec powiem po co korzystac z wyjatkow
MeMeKano jest kilka powodo
MeMeK1. przydaja sie w bibliotekach
MeMeK2. gdy pozyczamy funkcje kolegom :>
MeMeK3. gdy nie ma innego wybory
13:29MeMeKnalezy tez pamietac
MeMeKze nie powiennismy korzystac z mechanizmu wyjatkow
MeMeKna sile
MeMeKwszystko dla ludzi
MeMeK;>
MeMeKno to juz chyba tyle
MeMeKthx wszystkim za uwage