zatím nic moc, skoro nic nemám a není to moc podrobné Poznámka: Příklady jsou zjednodušené a ne vždy jsou 100% syntakticky právně (nechci vždy psát int main(void)... etc.) # Principy objektového programování 1) Jaký je rozdíl mezi třídou a objektem? **Třída je šablona pro vytváření objektů**. Typicky napíšu třídu a pak z ní inicializuju její objekty, které až poté v kódu využívám. ```cpp class Trida { public: int cislo; // tady jsou funkce a promenne }; int main(void) { Trida objekt; objekt.cislo = 10; } ``` 2) Jak je určena viditelnost členských proměnných a metod? - public -> přístup možný odkudkoli z programu - protected -> přístup je možný ze třidy nebo z podtříd (dědičnost) - private -> pouze funkce uvnitř objektu (třídy) můžou přistupovat ke členu s touto viditelností ```cpp class Trida { public: int a; private: int b; protected: int c; }; int main(void) { } ``` 3) Jaký je rozdíl mezi členskými metodami (a proměnnými) třídy a objektu? Třída může obsahovat i metody typu `static` to jsou **členské metody**. Pokud ze třidy inicializuju objekt, tyto metody se do objektu nepředají. Nejlepší způsob jak je zavolat je přes jejich třídu `Mojetrida::metoda();` 4) Jaký je rozdíl mezi klíčovými slovy protected a private? - **private** -> přístupné **POUZE** uvnitř třídy, zděděná třída (a její objekty) nemá přístup k k proměnné původní třídy s protected - **protected** -> vlastně je to jako private (tedy z kódu nemůžu měnit tuto proměnnou/metodu ve třidě), ale s tím rozdílem, že pokud vytvořím podtřídu (pomocí dědění) a z ní vytvořím objekt, tak jeho metody můžou přistupovat k protected členům objektů původní třídy - Co je polymorfismus a jak je ho dosaženo? - Co je to bázová třída a čím se vyznačuje? - Uveďte příklad deklarace plně virtuální metody? - Co je to implicitní konstuktor? - Co je to kopírovací konstruktor? - Jaké jsou možnosti dědění? Uveďte příklady. - Co je to virtuální dědění a k čemu je dobré? - Které vlastnosti rodiče potomek nedědí? - Co je to přetížení? Uveďte příklad (několik řádek kódu, ze kterých bude zřejmé, o co jde). - Jaký je rozdíl mezi přepsáním (override) a přetížením (overload)? - Co je vazba typu kompozice? Uveďte příklad (několik řádek kódu, ze kterých bude zřejmé, o co jde). - Co je vazba typu asociace? Uveďte přiklad (několik řádek kódu, ze kterých bude zřejmé, o co jde). - Co reprezentuje klíčové slovo this? - Jaký je rozdíl mezi referencí a ukazatelem? - Jaký je rozdíl mezi mělkou a hlubokou kopií? # Programování v C++ ### 1) Napište příklad načteni hodnoty typu int ze standarního vstupu pomocí proudového operátoru. Jak lze ošetřit správnost vstupu? ### 2) Jak se v C++ provádí přetížení operátoru? Uveďte příklad. ### 3) Jaké operátory nelze v C++ přetížit? ### Jak a kdy se volá konstruktor a destruktor? ### Jaký je rozdíl mezi objektem alokovaným v zásobníku a objektem dynamicky alokovaným na haldě? ### Jaký je rozdíl mezi operátory `delete` a `delete[]`? ### Jaká je návratová hodnota destruktoru? ### Co je třeba zajistit při dynamické alokaci? Uveďte příklad. ### Co je to výjimka a k čemu je dobrá? Uveďte příklad. ### Kolik výjimek je možné v programu ošetřit? ### Co je to generická funkce? ### Jak lze vytvořit explicitní instanci generické funkce? K čemu je to dobré? ### Jak jsou obvykle parametrizovány šablony tříd? ### V čem spočívá problém vícenásobného dědění? Jak je možné tomuto problému zabránit? ### Co je to zapouzdření a čemu je dobré? ### Jak lze využít implicitní hodnoty argumentu funkce? Uveďte příklad. ### Jaký je rozdíl mezi deklarací třídy pomocí class a struct? ### Co je to konverzní konstruktor? ### Jaký je rozdíl mezi statickou a dynamickou vazbou? ### Jaký je význam klíčového slova auto? Lze ho použít vždy? ### Co přesouvací (move) kontruktor? ### Co je pravidlo tří (rule of three)? ### Jaký je tvar definice lambda funkce v C++? Uveďte příklad a popište, co funkce dělá. # STL kontejnery ### 1) Co je to kontejner? Kontejnery jsou datové struktury určené k ukládání kolekce dat (hodnot) a k manipulaci s nimi. Například to je `vector`, který funguje jako dynamické pole. Máme různé typy kontejnerů - sekvenční asociativní (a pak údajně neseřazený asociativní a adaptery pro jiné ovládání existujících kontejnerů, ale to raději neřešme). Viz. další otázka. Hlavní smysl kontejnerů je ulehčit práci při programovaní. Je to často již implementované řešení, které se v kódu jednoduše používá, nebo je to rada, jak si takové řešení udělat. Je to vrstva abstrakce. ### 2) Jaký je rozdíl mezi sekvenčními a asociativními kontejnery? Uveďte příklad. **Sekvenční kontejnery** pracují s daty nezávisle na jejich hodnotě. To je míněno tak, že třeba data ukládají dle pořadí, ve kterém do kontejneru přišli a data mají unikátní index. Je to například `std::vector` a `std::list` **Asociativní kontejnery** řeší data většinou dle nějakého klíče, který je k nim přiřazen. Například `std::map`. Data jsou pak seřazena tak, aby bylo například efektivní vyhledávání a místo indexu mají právě na vyhledání klíč. - `std::map` - data seřazeny dle porovnávací funkce - `std::unordered_map` - data neseřazeny a hledány dle jejich hashe ### 3) Jaké jsou klíčové vlastnosti kontejneru std::vector? **Vector** je prakticky **dynamické** **pole** s podobnými vlastnostmi jako jeho implementace v C++, akorát to celé někdo implementoval v třídě s funkcemi za nás. - Data jsou seřazeny za sebou dle jejich velikosti v paměti. (tedy 5 prvek int o velikosty 4 byty je na 17-20 bytu) - Vyhledávání konkrétního prvku je O(1) -> dopočítám hned z velikosti a pozice - přidání/odstranění na konec - O(1) - Odstranění a přidání je kamkoli - O(n) -> vyžaduje přesun všech prvků v poli - pole má hodnotu velikosti (kolik zabírá bytů prvky) a kapacity (kolik bytů si dynamicky rezervuje). Kapacita musí být větší než velikost, jinak je třeba přealokovat - adresy prvků nejsou stabilní kvůli realokaci `std::vector kontejner1`; ### 4) Jaké jsou klíčové vlastnosti kontejneru std::map? Ukládá si pro každý prvek 2 hodnoty a to **klíč a hodnotu**. Všechny prvky jsou seřazené podle klíče a jeho porovnávací funkce, který zajišťuje operace o O(log n). Seřazení může třeba být binární strom. Kontejner umožňuje vymyslet a vložit vlastní porovnávací funkci v šabloně. ### 5) Jaké jsou klíčové vlastnosti kontejneru std::list? List je kontejner, který vlastně není moc odlišný od toho, co by člověk čekl (pokud si to pamatuje). Data jsou uložena každá ve vlastní buňce v paměti. Každá buňka umožňuje přístup k dalšímu a předchozímu prvku (pamatuji se jejich ukazatele). - proto je každá buňka bezpečně samostatně uložena v paměti nezávisle na ostatních buňkách - Je jednoduché přidávat/odebírat na známé pozice prvky - O(1) -> stačí změnit ukazatele v buňkách předchozí a další buňky (říká se tomu často uzel). - Hledání prvku na n-té pozice je obtížné, je třeba projít všechny prvky, které k němu vedou - O(n) - vhodné pro potřebu čistého rychléhi přidávání a mazaání prvků, ale nevhodné pro rychlý náhodný přístup `std::list L;` ### 6) Jakého datového typu může být klíč kontejneru std::map? Klíč `std::map` může být kteréhokoli typu, který je možná porovnávat pomocí řazení (má operátor `>` a `<`). Nebo je možné dodat vlastní porovnávací funkci (komparátor). ### 7) Co je třeba zajistit v případě, že klíčem v kontejneru std::map je strukturovaný datový typ (např. naše vlastní třída)? - buď je třeba zajistit, aby objekty třídy byly porovnatelné pomocí `>` a `<` například pomocí přetěžování operátorů - nebo je možné sepsat vlastní comparator (vlastní porovnávací funkci) ### 8) Jaký je význam datového typu std::pair? `std::pair` je datový typ, který umí ukládat 2 prvky libovolného typu ```cpp pair p = {1, "ahoj"}; p.first = 7; p.second = "krkavců"; ``` vhodné je se i podívat na operaci vzájemného porovnávání párů ### 9) Co je to iterátor? Uveďte příklad. Iterátor je třída, která je spojená s určitým kontejnerem. Úkol prvků této třídy je jednoduchý a to umožnění jednoduché procházení prvky kontejneru. Iterátor by tedy měl být dereferencovatelný -> dereferencí `*it` získáme hodnotu nynějšího prvku, jako by to byl ukazatel. Dále přičtením `++it` získáme další prvek kontejneru. Iterátoru přiřadíme hodnotu pomocí funkcá `.begin()` -> hodnota prvního iterátoru, a zjišťujeme konec kontejneru pomocí `.end()`. Příklad: ```cpp std::vector pole = {1, 2, 3}; std::vector::iterator it = pole.begin(); for(std::vector::iterator it = pole.begin(); it != pole.end(); ++i) { std::cout << *it << std::endl; } ``` ### 10) Jaký je rozdíl mezi konstantním a nekonstantním iterátorem? - Pomocí **nekontantního** iterátoru můžu měnit hodnotu prvku, na který ukazuje. - Hodnotu prvku na který ukazuje **konstantní** iterátor měnit nemůžu. - Potřebuji změnit typ iterátoru a také používám speciální funkci ```cpp std::vector pole = {1, 2, 3}; std::vector::iterator it = pole.begin(); std::vector::const_iterator cit = pole.cbegin(); //vlastni funkce *it = 10; //můžu *cit = 20; //nesmim, je to const... ``` ### 11) Co všechno je třeba zajistit pro vytvoření vlastního iterátoru? - iterátor musí mít dereferenci -> lze získat hodnotu jeho prvku - lze přičítat takto `++it` - lze odčítat takto `--it' - lze porovnávat `==` a `!=` -> hlavně pro `.begin()` a `.end()` zbytek podle kontejneru a kontextu (a podle toho, jak je vlastně vůbec myšlena tato otázka) - je třeba mít `end` a `begin`, konstruktor u kontejneru etc... ### 12) Co je range-for cyklus? Uveďte příklad. Je to specifický zápis `for` loop, který umžňuje iterovat všemi prvkami kontejneru. ```cpp std::vector pole = {1, 2, 3}; for (auto &i : pole) { i++; } ``` V tomto kódu se projedou všehny hodnoty vektoru a přičte se k ním jedna. `for (auto &i : pole)` -> napravo je název pole, nalevo je hodnotu prvku, používá se auto s referencí, aby se fyzicky nekopíroval každý prvek a bylo to nezávislé na typu. prvek `i` pak reprezentuje aktuálně prvek iterace, tedy nabere hodnotu každého prvku pole **Obdobně lze udělat loop i pro iteraci listem**. ### 13) Uveďte příklad použití algoritmu sort (deklarujte vektor libovolného datového typu, vložte do něj data a vektor seřaďte). ```cpp #include #include #include int main() { std::vector v = {5, 2, 9, 1, 7}; std::sort(v.begin(), v.end()); for (const auto& x : v) { std::cout << x << " "; } return 0; } ``` Sort porovná prvky podle jejich operárů `<` a `>`, funguje univerzálně u všech typů, pokud mají porovnávání definované. U stringů to třeba porovnává lexikograficky. Jinak je třeba definovat `>` `<` pomocí přetěžování operátorů a nebo dodat vlastní porovnávací funkci. -> `std::sort(v.begin(), v.end(), comparator)` -> kde comparator je porovnávací funkce # Praktické programování (Qt a související) - Co je to event-driven programování? - Jaký je rozdíl mezi událostí a signálem? - Uveďtě příklady událostí v Qt a jejich využití. - Popište systém signálů a slotů, uveďte příklad propojení. - Jakým způsobem lze vytvořit v Qt okno a v něm vykreslit grafickou komponentu? - Jak lze měnit grafickou podobu jednotlivých Qt komponent? - Co se časovač (QTimer), k čemu je dobrý a jak se používá? - Co si představujete pod pojmem MVC? - Jaký je rozdíl mezi UDP a TCP transportní vrstvou? - Co je to REST rozhraní?