Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

public:pb161_fall14_cviko11_774336 [2018/02/24 19:10] (aktuální)
Řádek 1: Řádek 1:
 +====== Cvičení 11 ======
 +===== Úvod do cvičení =====
 +Dnes si vyzkoušíte základní práci se šablonami. Kromě tvorby jednoduchého kontejneru podobného std::array z C++11 si vyzkoušíte specializaci šablony a automatické odvození typu.
  
 +Stáhněte si [[https://​www.fi.muni.cz/​~xbrukner/​cviko11.zip|předpřipravený projekt]].
 +
 +Pro testování unit testy je použit framework [[https://​github.com/​philsquared/​Catch/​|Catch]]. Není potřeba nic stahovat, vše je součástí staženého projektu. Zde najdete [[https://​github.com/​philsquared/​Catch/​blob/​master/​docs/​tutorial.md|tutoriál]] (bude potřeba jen pro jeden úkol).
 +===== První úkol =====
 +Pro první úkol máte k dispozici třídu Five, která v sobě uschová 5 prvků typu int. Vaším úkolem bude z této třídy udělat kontejner pro libovolný typ a libovolný počet prvků.
 +
 +Upozornění - váš kontejner bude schopen korektně uchovávat jen primitivní typy, neboť nebude možnost předat parametry konstruktorům jednotlivých prvků.
 +
 +==== Zadání úkolu ====
 +  * Protože třída moc neumí, dopište metody set(index, int) a get(index) pro přístup k prvkům. Index je typu unsigned.
 +  * Udělejte kopii této třídy a přejmenujte ji na Container. Z této udělejte šablonu, která má jeden typový parametr. Výsledná třída tedy bude uchovávat pět prvků typu, který se mu předá jako šablonový parametr.
 +    * Bezparametrický konstruktor nastaví všechny položky na 0 výsledného typu.  ​
 +    * Vytvořte typedef value_type, který bude definovat typ prvků.
 +    * Napište operátor== pro kontejner obsahující stejný typ se stejnou velikostí prvků. Stejně tak operátor !=.
 +  * Přidejte druhý parametr do šablony, který určuje počet prvků. Nastavte mu obecnou hodnotu 5. Ujistěte se, že všechny metody fungují.
 +
 +===== Druhý úkol =====
 +Šablony mohou být specializovány podle parametru, který dostanou. Vaším úkolem bude napsat specializaci pro typ bool.
 +
 +==== Zadání úkolu ====
 +  * Vytvořte specializaci pro typ bool.
 +    * V původní třídě i ve specializaci vytvořte statickou metodu isSpecialized(),​ která vrací true ve specializaci a false v původní třídě.
 +    * V mainu ji zkuste použít a ujistěte se, že je použita specializace (pomocí výše zmíněné metody).
 +  * Upravte tuto specializaci,​ aby nepoužívala pro uložení bool (který rozhodně nezabírá jeden bit), ale char a aby pro uložení jednoho prvku se použil právě jeden bit.
 +    * Budete používat bitové operace.
 +    * Pokud bude počet prvků dělitelný osmi, měl by každý používat jeden bit. Pokud ne, tak se použije o jeden byte více. Tedy pro uložení 16 prvků se použijí dva byty (chary), pro 18 prvků tři.
 +    * Typedef value_type je stále bool.
 +  * Napište unit test, který vyzkouší vaši specializaci.
 +    * Test, který otestuje uložení a čtení prvků.
 +    * Test kontrolující operátor porovnání.
 +    * Test ověřující využití prostoru za pomoci sizeof. Ten musí být pro daný počet prvků menší než sizeof(bool) * počet prvků. (//​Upozornění - je možné, že to nebude přesně počet prvků/8, neboť třída bude obsahovat nějaké další informace, nejen pole prvků.//)
 +
 +===== Třetí úkol =====
 +Důležitou vlastností C++ kompilátoru je, že je schopen odvodit typ pro šablonu z parametrů - není tedy potřeba je vždy uvádět. Toto si vyzkoušíte na callbacku.
 +
 +==== Zadání úkolu ====
 +  * Vytvořte globální funkci countNonZero(int value), která dostane hodnotu, a pokud není  nula, zvětší globální čítač (pojmenovaný counterNonZero) o 1. Zároveň s tím vytvořte ve třídě Container (nikoliv ve specializaci) konstantní metodu forEach(), která zavolá parametr (callback) pro každou hodnotu v kontejneru. ​
 +    * Typ parametru bude void(*callback)(T) - definuje proměnnou jménem callback, což je ukazatel na funkci, která vrací void a bere jeden parametr typu T (template argument Container).
 +    * Tento pointer na funkci se pak používá takto - (*callback)(parametr).
 +    * Tuto metodu otestujte.
 +  * Vytvořte šablonovou třídu Count, která bude též počítat počet výskytů čísel větší než nula. Jen výsledek bude ukládat do atributu této třídy, a bude se volat pomocí operátoru (). Typ, který bude tento operátor brát, bude parametr třídy.
 +    * Počet zavolání zjistíte zavoláním metody getCount.
 +    * Vytvořte druhou implementaci metody forEach (tentokrát i ve specializaci),​ která bere jako parametr referenci na instanci třídy Count.
 +    * Jak třídu Count, tak druhou implementaci metody forEach otestujte.
 +  * Všimněte si, že obě implementace metody forEach() mají v podstatě stejné tělo. Nešlo by obě metody sjednotit? Šlo :-)
 +    * Vytvořte šablonovou metodu forEach(), která má šablonový typ typ callbacku.
 +    * Protože C++ kompilátor je schopen typ odvodit, není potřeba ho specifikovat.
 +    * Pro korektní otestování bude potřeba původní metody smazat. (Proč?)
 +
 +
 +===== Vzorové řešení =====
 +
 +[[https://​www.fi.muni.cz/​~xbrukner/​cviko11-solution.zip|Vzorové řešení]].
 +
 +Autorem této úlohy je Tomáš Brukner - xbrukner (zavináč) fi.muni.cz.
QR Code
QR Code public:pb161_fall14_cviko11_774336 (generated for current page)