8. cvičení

Konstruktory pro vlastní struktury

Pokud definujeme strukturu tím nejjednodušším způsobem, např. pro reprezentaci racionálních čísel pomocí zlomku:

struct Zlomek
{
    int citatel;
    int jmenovatel;
};

Potom při vytvoření proměnné tohoto typu vzniknou neinicializované hodnoty, podobně jako při vytváření proměnných základního číselného typu. Inicializaci můžeme provést buďto ručně explicitním zápisem hodnot do všech složek, např.:

Zlomak z;
z.citatel = 0;
z.jmenovatel = 1;

Alternativně můžeme počáteční hodnoty uvést přímo při vytváření proměnné pomocí složených závorek:

Zlomek z = {0, 1};

Jazyk C++ ale umožňuje specifikovat počáteční hodnoty přímo při definici struktury:

struct Zlomek
{
    int citatel = 0;
    int jmenovatel = 1;
};

Takto definované počáteční hodnoty se použijí vždy při vytváření proměnných tohoto typu, pokud neuvedeme počáteční hodnoty jiným způsobem (viz dále):

// tímto příkazem dojde k inicializaci (citatel = 0, jmenovatel = 1)
Zlomek z;

// dále můžeme s atributy struktury dělat co chceme
z.citatel = 1;
z.jmenovatel = 2;

Současně ale touto změnou definice struktury přestal fungovat předchozí způsob předání počátečních hodnot pomocí složených závorek, což je pozůstatek z jazyka C:

Zlomek z = {0, 1};

Abychom mohli podobným způsobem „předefinovat“ počáteční hodnoty v jazyce C++ a nemuseli explicitně vypisovat názvy jednotlivých složek (z.citatel = ..., z.jmenovatel = ...), použijeme tzv. konstruktor. Konstruktor v jazyce C++ je speciální funkce, která je úzce svázána s danou strukturou a stará se o inicializaci jejích atributů. Naše struktura výše už má jeden implicitní konstruktor, který nemá žádné parametry a nastaví hodnotu čitatele na 0 a hodnotu jmenovatele na 1. Vlastní konstruktor se dvěma parametry můžeme definovat např. takto:

struct Zlomek
{
    int citatel = 0;
    int jmenovatel = 1;

    // konstruktor se 2 parametry
    Zlomek(int c, int j)
    {
        citatel = c;
        jmenovatel = j;
    }
};

Název konstruktoru musí odpovídat názvu struktury (Zlomek), konstruktor nemá žádný návratový typ, a v kulatých závorkách uvedeme parametry konstruktoru (jejich volba záleží na nás). Tento konstruktor můžeme použít např. takto:

Zlomek z(2, 3);

nebo takto:

Zlomek z = Zlomek(2, 3);

Přidáním tohoto konstruktoru ale přestal fungovat první způsob vytváření proměnných bez parametrů (Zlomek z;), protože implicitní konstruktor zmizel. Abychom tuto funkčnost obnovili, musíme přidat vlastní konstruktor bez parametrů (který ale může zůstat bez příkazů):

struct Zlomek
{
    int citatel = 0;
    int jmenovatel = 1;

    // konstruktor se 2 parametry
    Zlomek(int c, int j)
    {
        citatel = c;
        jmenovatel = j;
    }

    // konstruktor bez parametru (pouziji se pocatecni hodnoty 0 a 1 definovane vyse)
    Zlomek() {}
};

Domácí úkol – počítání se zlomky

Vytvořte program, který bude umět provádět matematické operace se zlomky – sčítání, odčítání, násobení a dělení. Všechny výsledky by se měly vypisovat jako zlomky v základním tvaru, tj. po zkrácení by největší společný dělitel čitatele a jmenovatele měl být 1 a jmenovatel by měl být kladné číslo. Dále by program měl správně pracovat s nulami, aby nevypisoval nesmyslné výsledky.

V programu buď proveďte a vypište všechny operace, nebo dejte uživateli na výběr, kterou operaci chce provést.

Bonus: Upravte chování programu tak, aby co nejvíce připomínalo klasickou kalkulačku, kde se výsledek uloží v mezipaměti a může se použít v další operaci (např. přičtení nebo odečtení nové hodnoty od mezivýsledku).

Tento úkol je potřeba splnit do neděle 22. 11. 2020. Vypracované programy ve formě zdrojového kódu mi posílejte emailem.