share:truealiases:- Bez názvu
complete:trueauthor: Petr
OOP, polymorfismus
Cite
Objektově orientované programování v C++
Zapouzdření
Dědičnost
Atributy a metody
Statické atributy a metody
Virtuální metody
Polymorfismus
Abstraktní třídy
Výjimky
Šablony
Přetěžování operátorů
Mělká a hluboká kopie
Objektové programování obecně
OOP
Rozděluje problém a určuje entity
Interakce mezi entitami (interface(metody))
Základem je objekt to je instance třídy
Objekt je obdoba proměnné z neobjektového programování
Obdobou datového typu je třída
Definuje proměnné (atributy) objektu
Definuje metody (interface) objektu
Objekt má nějaký vnitřní stav, reprezentovaný hodnotami atributů (členských proměnných)
Operace nad objekty se nazývají metody (členské funkce)
OOP vzniklo snahou popsat a modelovat okolní svět v počítači
OOP urychluje vývoj a zjednodušuje znovupoužitelnost odladěného kódu
Každá třída má při vytvoření konstruktor a destruktor
Lze přetížit, implicitně pomocí New, Delete
Volá se automaticky
Zapouzdření
Specifikovat přístup k atributům a metodám
Public — přístupné zvenčí třídy
Private — přístupné pouze zevnitř konkrétní třídy (a z friend funkcí)
Protected — podobné private, ale dostupné navíc potomkům třídy
Třída a struct jsou podobné, liší se jen v implicitní vidětelnosti
Class - Private
Struct - Public
Přistupuje se pomocí tečkové notace
K private proměným lze implementovat gettry a settry, ty lze měnit, bez změny rozhraní
Friend funkce stojí mimo třídu
může přistupovat k private proměným
lze volat z globalu
Dědičnost
Mezi třídami může být vztah rodič — potomek
Potomek od rodiče může dědit atributy a metody
Stejně tak jako každá třída si může vytvořit svoje atributy a metody
Protected jsou přístupné z potomka, jinak ekvivalentní s private
Navíc může přepsat metodu předka
Statické metody a atributy
Nejsou součástí objektu, ale třídy jako takové (instanční vs třídní)
Musí se uložit mimo objekty
Statické metody nemohou používat nestatické položky
Klíčové slovo Static
Nevolají se na objekty jako takové
Neumožňuje polymorfismus
Virtuální metody
Pro každou třídu existuje tabulka virtuálních metod
Podle VMT (virtual method table) se za běhu dle typu objektu vybere, jaká metoda se má použít (z aktuálního typu, nebo podtřídy)
Aby šlo této dynamické vazby využít, musí být objekt referencován ukazatelem, přímo to nejde
Klíčové slovo Virtual
Override přepisuje funkci od předka
Polymorfismus
Ukazatel na nadtřídu může ukázat i na podtřídu
Objekt se chová podle toho, které třídy je instancí
Tedy se volají správné metody podtřídy a ne nadtřídy
Volaná metoda se určí až v okamžiku volání Abstraktní třídy
Obsahují alespoň jednu abstraktní metodu, nemůže mít instance
Abstraktní metoda je pouze deklarovaná, není definovaná (až v podtřídě)
Výjimky
Exceptions C++ only
Způsob ošetření chyb za běhu programu v C++, klíčové slovo "throw"
Pro efekt musí být "testovaný" kód v "try" bloku, v catch bloku se následně případná výjimka zpracuje (ovladač vyjímek)
Při vyhození výjimky se vykonávání kódu zastaví, a postupně se skáče nahoru a čistí zásobník (a volají destruktory objektů) k nejbližšímu "ovladači" výjimek
Ovladač musí obsahovat jen ty vyjímky co lze zpracovat
Pokud vyjímka nenajde ovladač šíří se až do mainu, případně zabije main
Catch chytí všechny vyjímky, throw může propagovat výš
Parametrizovaná deklarace (a definice) funkce/třídy, ze které kompilátor dosazením za parametry vytvoří instanci šablony
Parametr T šablony může být typ argumentů, typ proměnných, návratových hodnot
Až použití šablony generuje kód
V .h souborech
pro třídy vyžaduje inline funkce, nebo templaty funkcí
Přetěžování operátorů
Operátory je možné přetížit podobně jako funkce/metody
Lze přetížit (friend) funkcemi, nebo metodami na objektech/třídách
Klíčové slovo "operator"
Nemění se priorita ani asociativita operátorů, ale mění se typy operandů a sémantika operací
Přetížit lze pouze existující operátory
Někdy je lepší psát metodu
Mělká a hluboká kopie
Mělká kopie
Kopie objektu obsahuje ukazatele/reference na stejná data
Je nutné vyřešit destruktor, aby data uvolnil až je nic nebude používat
Lze řešit počítáním referencí
std::shared_ptr
Kopie nejsou nezávislé
Hluboká kopie
Kopie objektu si zkopíruje všechna dynamicky alokovaná data na nové místo
Při destrukci objektu se data vždy uvolní
Data se v kopiích po čase mohou lišit
Náročnější (paměť, přesuny)
Lze pomoci copy-on-write
Často, když objekt obsahuje přímo dynamicky alokovaná data (ne v dalším objektu, který to má vyřešené jako vector), tak se hodí vytvořit vlastní operátor přiřazení, kopírující konstruktor a destruktor
Kopírovací konstruktor volá defaultně konstruktory jednotlivých prvků (ne vždy vhodné)