C++ přetěžování funkcí a operátorů. Jan Hnilica Počítačové modelování 19

Podobné dokumenty
přetížení operátorů (o)

Základy C++ I. Jan Hnilica Počítačové modelování 18

Mělká a hluboká kopie

Více o konstruktorech a destruktorech

Jazyk C++ I. Polymorfismus

přetížení operátorů (o)

Pokročilé programování v jazyce C pro chemiky (C3220) Třídy v C++

Programování v C++ 3, 3. cvičení

Přetěžování operátorů

Přetěžování operátorů

PŘETĚŽOVÁNÍ OPERÁTORŮ

PB161 Programování v jazyce C++ Přednáška 4

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Konstruktory a destruktory

Pointery II. Jan Hnilica Počítačové modelování 17

Vector datový kontejner v C++.

PB161 Programování v jazyce C++ Přednáška 9

Funkční objekty v C++.

Pokročilé programování v jazyce C pro chemiky (C3220) Pokročilá témata jazyka C++

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

8 Třídy, objekty, metody, předávání argumentů metod

Projekt Obrázek strana 135

Polymorfismus. Časová náročnost lekce: 3 hodiny Datum ukončení a splnění lekce: 30.března

C++ objektově orientovaná nadstavba programovacího jazyka C

Programování v C++ VI

for (int i = 0; i < sizeof(hodnoty) / sizeof(int); i++) { cout<<hodonoty[i]<< endl; } cin.get(); return 0; }

Programování v C++ 1, 5. cvičení

Úvod do programovacích jazyků (Java)

Mnohotvarost (polymorfizmus)

Algoritmizace a programování

PROGRAMOVÁNÍ V C++ CVIČENÍ

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016

Dědění, polymorfismus

Přetěžování operátorů, dynamika objektů 2

ZPRO v "C" Ing. Vít Hanousek. verze 0.3

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

Standardní algoritmy vyhledávací.

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. December 7, 2016

Jazyk C++ II. Šablony a implementace

Programování v C++ 2, 4. cvičení

Př. další použití pointerů

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

7. přednáška - třídy, objekty třídy objekty atributy tříd metody tříd

Programování v C++, 2. cvičení

Programování v C++ 1, 6. cvičení

Úvod do programování. Lekce 1

Pole stručný úvod do začátku, podrobně později - zatím statická pole (ne dynamicky) - číslují se od 0

Jazyk C# (seminář 6)

5 Přehled operátorů, příkazy, přetypování

PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

SYSTÉMOVÉ PROGRAMOVÁNÍ Cvičení č.1

Programování v jazyce C a C++

int ii char [16] double dd název adresa / proměnná N = nevyužito xxx xxx xxx N xxx xxx N xxx N

Jazyk C++ 1. Blok 3 Objektové typy jazyka C++ Třída. Studijní cíl. Doba nutná k nastudování. Průvodce studiem

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Algoritmizace a programování

DUM 06 téma: Tvorba makra pomocí VBA

Objektov orientované programování. C++ Akademie SH. 7. Objektov orientované programování. Michal Kvasni ka. Za áte níci C++ 2.

Paměť počítače. alg2 1

Ukazatel (Pointer) jako datový typ - proměnné jsou umístěny v paměti na určitém místě (adrese) a zabírají určitý prostor (počet bytů), který je daný

Zpracoval:

Standardní algoritmy v C++.

Programování v jazyce C a C++

Pokročilé programování v jazyce C pro chemiky (C3220) Statické proměnné a metody, šablony v C++

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Operátory, výrazy. Tomáš Pitner, upravil Marek Šabo

Stručný obsah První týden Druhý týden 211 Třetí týden 451 Rejstřík 787

Výčtový typ strana 67

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

Výrazy a operátory. Operátory Unární - unární a unární + Např.: a +b

Statické proměnné a metody. Tomáš Pitner, upravil Marek Šabo

Základy programování (IZP)

Pole a kolekce. v C#, Javě a C++

PB161 Programování v jazyce C++ Přednáška 4

Programování II. Návrh programu I 2018/19

Chování konstruktorů a destruktorů při dědění

Ukazatele a pole. Chceme-li vyplnit celé pole nulami, použijeme prázdný inicializátor: 207 Čárka na konci seznamu inicializátorů

Jazyk C++ I. Šablony 2

Lineární spojový seznam (úvod do dynamických datových struktur)

Proměnná. Datový typ. IAJCE Cvičení č. 3. Pojmenované místo v paměti sloužící pro uložení hodnoty.

Abstraktní třídy, polymorfní struktury

map, multimap - Asociativní pole v C++.

Ukazatele, dynamická alokace

Objektově orientované programování

Úvod do programovacích jazyků (Java)

Iterátory v C++. int pole[20]; for (int *temp = pole, temp!= &pole[20]; temp++) { *temp = 0;

- dělají se také pomocí #define - podobné (použitím) funkcím - předpřipravená jsou např. v ctype.h. - jak na vlastní makro:

IAJCE Přednáška č. 8. double tprumer = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; Console.Write("\nPrumerna teplota je {0}", tprumer);

Programování v C++ 1, 14. cvičení

<surface name="pozadi" file="obrazky/pozadi/pozadi.png"/> ****************************************************************************

konstruktory a destruktory (o)

Ukazka knihy z internetoveho knihkupectvi

Datové typy strana 29

PB161 Programování v C++ Proudy pro standardní zařízení Souborové proudy Paměťové proudy Manipulátory

Množina v C++ (set, multiset).

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Úvod Třídy Rozhraní Pole Konec. Programování v C# Hodnotové datové typy, řídící struktury. Petr Vaněček 1 / 39

Pokročilé programování v jazyce C pro chemiky (C3220) Dědičnost tříd v C++

Transkript:

C++ přetěžování funkcí a operátorů 1

Přetěžování funkcí jazyk C++ umožňuje napsat více funkcí se stejným názvem, těmto funkcím říkáme přetížené přetížené funkce se musí odlišovat typem nebo počtem parametrů, případně obojím (nestačí odlišení typem návratové hodnoty) // funkce pro výpis pole proměnných int void VypisPole(int pole[], int pocetprvku) for (int i = 0; i < pocetprvku; i++) cout << pole[i] << ' '; cout << endl; ; // další funkce pro výpis polí jiných typů pojmenujeme stejně void VypisPole(double pole[], int pocetprvku); void VypisPole(float pole[], int pocetprvku); void VypisPole(long pole[], int pocetprvku); nemusíme vymýšlet pro každý datový typ jiný název funkce, která vypíše pole pro všechny typy máme stejně pojmenovanou funkci VypisPole kompilátor podle seznamu parametrů pozná, kterou má zavolat 2

Přetěžování členských funkcí třídy příklad: třída obdélník má (kromě přístupových funkcí) metodu Nakresli class obdelnik public: // pristupové funkce int VratVysku() const; void NastavVysku(int v); int VratSirku() const; void NastavSirku(int s); // ostatní funkce void Nakresli() const; private: int vyska, sirka; ; funkce Nakresli vykreslí na monitor obdélník z hvězdiček: void obdelnik::nakresli() const for (int i = 0; i < vyska; i++) for (int j = 0; j < sirka; j++) std::cout << '*'; std::cout << std::endl; pokud chceme, aby se obdélník uměl nakreslit i pomocí jiného znaku než '*', přetížíme funkci Nakresli, tj. vytvoříme ještě jednu její variantu, která bude přebírat jako parametr znak, jenž má být při kreslení použit 3

Přetěžování členských funkcí třídy class obdelnik public: // pristupové funkce int VratVysku() const; void NastavVysku(int v); int VratSirku() const; void NastavSirku(int s); // ostatní funkce void Nakresli() const; void Nakresli(char z) const; private: int vyska, sirka; ; void obdelnik::nakresli() const Nakresli('*'); void obdelnik::nakresli(char z) const for (int i = 0; i < vyska; i++) for (int j = 0; j < sirka; j++) std::cout << z; std::cout << std::endl; třída má teď dvě funkce Nakresli, první (bez parametrů) kreslí obdélník z hvězdiček, druhá použije ke kreslení znak předaný jako parametr v definici funkce bez parametrů je pouze zavolána varianta s parametrem, které je předán defaultní znak hvězdičky to proto, abychom neopakovali stejný kód ve více funkcích i když bychom mohli funkci Nakresli() vypsat celou (kompilátoru by to nevadilo), je zvykem vyvarovat se opakování stejného kódu 4

Přetěžování členských funkcí třídy použití obdélníka a jeho přetížených funkcí: int main() using namespace std; obdelnik O; O.NastavVysku(5); O.NastavSirku(10); cout << "vyska: " << O.VratVysku() << endl; cout << "sirka: " << O.VratSirku() << endl; cout << endl; O.Nakresli(); cout << endl; O.Nakresli('#'); return 0; 5

Přetěžování konstruktorů třídy konstruktor lze přetížit stejně jako kteroukoliv jinou metodu, jedná se o silnou vlastnost C++ Pravidla: 1. pokud nenapíšeme ke třídě žádný konstruktor, kompilátor poskytne konstruktor bez parametrů (tzv. výchozí), který ale s datovými položkami třídy nic nedělá 2. pokud napíšeme jakýkoliv konstruktor, kompilátor neposkytne žádný chceme-li, abychom mohli ihned při vytvoření nastavit výšku a šířku obdélníka, napíšeme konstruktor přebírající jako parametry dvě celá čísla: // deklarace konstruktoru obdelnik(int v, int s); // definice konstruktoru obdelnik::obdelnik(int v, int s) vyska = v; sirka = s; použití konstruktoru v programu: obdelnik O(5, 10); O.Nakresli(); 6

Přetěžování konstruktorů třídy protože jsme ale napsali vlastní konstruktor, kompilátor neposkytl žádný, není tedy možné napsat obdelnik O; protože třída aktuálně nemá žádný výchozí konstruktor výchozí konstruktory jsou potřeba pokud např. chceme vytvořit pole objektů: obdelnik pole[10]; pokud není k dispozici výchozí konstruktor, tento příkaz povede k chybě v době kompilace pokud už tedy máme napsaný nějaký konstruktor, musíme výchozí konstruktor doplnit sami // deklarace konstruktorů obdelnik(); obdelnik(int v, int s); // defince konstruktorů obdelnik::obdelnik() obdelnik::obdelnik(int v, int s) vyska = v; sirka = s; Třída má teď dva přetížené konstruktory. Výchozí konstruktor sice nic nedělá, ale i to stačí k tomu abychom mohli vytvořit - pole obdélníků obdelnik[10]; - obdélník bez parametrů obdelnik O; Bylo by však samozřejmě možné do těla výchozího konstruktoru doplnit kód sloužící k nastavení nějakých úvodních hodnot datových členů: obdelnik::obdelnik() vyska = sirka = 1; 7

Kopírovací konstruktor konstruktor, který si jako parametr bere odkaz na objekt dané třídy a má za úkol vytvořit jeho kopii (tzn. nastavit datové členy nového objektu podle předaného vzoru) // deklarace obdelnik(const obdelnik & vzor); // definice obdelnik::obdelnik(const obdelnik & vzor) vyska = vzor.vratvysku(); sirka = vzor.vratsirku(); v programu použijeme kopírovací konstruktor takto: Parametr vzor předaný odkazem se obvykle deklaruje jako konstantní, protože kopírovací konstruktor nemění jeho data. kopírovací knstruktor nastaví členská data podle předloženého vzoru obdelnik O(7, 4); // vytvoření nějakého obdélníka obdelnik P(O); // vytvoření jeho kopie - P má šířku a výšku stejnou jako O Kopírovací konstruktor je ke třídě automaticky poskytnut kompilátorem. Pokud třída nealokuje data na haldě, poskytnutý kopírovací konstruktor funguje správně a není potřeba psát vlastní. 8

Kopírovací konstruktor pro třídu alokující paměť na haldě následující třída čtverec má svou datovou položku strana alokovanou na haldě a udržuje si na ni pointer class ctverec public: // konstruktor, destruktor ctverec(int s); ~ctverec(); // pristupove funkce int VratStranu() const return *strana; void NastavStranu(int s) *strana = s; private: int *strana; ; // definice konstruktoru ctverec::ctverec(int s) strana = new int; *strana = s; Co se stane, když pro objekt této třídy použijeme vestavěný kopírovací konstruktor? 9

Kopírovací konstruktor pro třídu alokující paměť na haldě pokud použijeme vestavěný kopírovací konstruktor, dojde k přesnému nakopírování hodnoty proměnné strana (tedy paměťové adresy), oba čtverce (vzor i kopie) budou ukazovat na tutéž adresu v paměti ctverec C(5); // vytvoření čtverce ctverec Kopie(C); // vytvoření kopie ctverec C strana 5 ctverec Kopie strana pokud jednomu ze čtverců změníme hodnotu strany, změníme ji oběma pokud bude jeden z čtverců smazán, druhý bude ukazovat na neplatnou adresu aby k tomu nedošlo, je potřeba napsat vlastní kopírovací konstruktor, který pro nově vytvářený objekt alokuje paměť a zkopíruje do ní hodnotu datové položky vzoru // kopírovací konstruktor ctverec::ctverec(const ctverec & vzor) strana = new int; *strana = vzor.vratstranu(); ctverec Kopie(C); // vytvoření kopie ctverec C strana 5 5 ctverec Kopie strana 10

Přetížení operátorů vestavěné operátory (+, -, *...), které pracují se základními datovými typy (int, double...) lze přetížit tak, aby pracovaly i s nově vytvořenými typy třídami přetížené operátory mohou být a) běžnými funkcemi funkce má přesně tolik parametrů, kolik má operátor operandů operátor sčítání (+) bude mít dva parametry, operátor inkrementace (++) jeden b) metodami třídy operátory jako členské funkce mají v seznamu parametrů o jeden operand méně než by měly mít, protože jedním z operandů je automaticky ten objekt, jehož funkce je volána unární operátory (např. ++) jsou jako členské funkce bez parametrů (pracují na objektu samém) binární operátory (+, ==...) mají jeden parametr - objekt na pravé straně operátoru (levou stranou je objekt, jehož funkce byla volána) k přetěžování operátorů slouží klíčové slovo operator, za který píšeme daný operátor funkce, přetěžující operátor + se deklaruje takto: návratový typ operator+(seznam parametrů) 11

Přetížení operátorů k demonstraci principů přetěžování operátorů použijeme třídu cislo, která jako svoji jedinou datovou položku uchovává celočíselnou hodnotu (reálný smysl by měla např. třída matice...) // deklarace třídy class cislo public: cislo(int h); int VratHodnotu() const return hodnota; void NastavHodnotu(int h) hodnota = h; private: int hodnota; ; // definice konstruktoru cislo::cislo(int h) hodnota = h; 12

Operátory jako běžné funkce Binární oprátor: sčítání // deklarace přetíženého operátoru + cislo operator+(cislo a, cislo b); // definice cislo operator+(cislo a, cislo b) cislo c(a.vrathodnotu() + b.vrathodnotu()); return c; funkce, přetěžující operátor, má název složený z klíčového slova operator, za kterým následuje typ operátoru (v tomto případě +), následují závorky se seznamem parametrů (dva objekty typu cislo, které bude sčítat) návratovou hodnotou je objekt typu cislo (aby bylo možné výsledek sčítání přiřadit jinému objektu cislo) v těle funkce se vytvoří objekt typu cislo, kterému se nastaví hodnota rovná součtu hodnot operandů, tento objekt je funkcí vrácen cislo a(7), b(5), c(0); c = a + b; // použití přetíženého operátoru cout << hodnota c je << c.vrathodnotu(); 13

Operátory jako běžné funkce všimněme si, že přetížený operátor + nijak nemění hodnoty operandů (parametrů), pouze tyto hodnoty použije k nastavení hodnoty výsledku je tedy rozumné předávat operandy do funkce jako odkazy, funkce si nebude pořizovat jejich lokální kopie, ale bude pracovat přímo s předanými proměnnými pro jistotu deklarujeme operandy jako konstantní odkazy, budeme tak mít jistotu (ohlídanou kompilátorem), že se předané objekty skutečně nezmění // deklarace přetížení operátoru + cislo operator+(const cislo & a, const cislo & b); // definice cislo operator+(const cislo & a, const cislo & b) cislo c(a.vrathodnotu() + b.vrathodnotu()); return c; Obecně platí, že pokud funkce nemění předané parametry, je výhodné tyto parametry předávat jako (konstantní) odkazy. Nedochází tak ke zbytečnému pořizování lokálních kopií. 14

Operátory jako běžné funkce Unární oprátor: mínus chceme, aby mezi objekty cislo bylo možné používat unární mínus, tedy aby bylo možné napsat a = -b; musíme přetížit unární operátor - // deklarace cislo operator-(const cislo & a); // definice cislo operator-(const cislo & a) cislo b(-a.vrathodnotu()); return b; Parametr (operand) je opět předáván jako konstantní odkaz, funkce nemění jeho hodnoty. pozn. dočasný objekt b, který je ve funkci vytvořen, není nutné pojmenovávat: cislo operator-(const cislo & a) return cislo(-a.vrathodnotu()); 15

Operátory jako běžné funkce Unární operátor: inkrementace operátor inkrementace má dvě formy 1. prefixovou ++x (zvyšuje hodnotu x o jedničku, vrací zvýšenou hodnotu) 2. postfixovou x++ (zvyšuje hodnotu x o jedničku, ale vrací původní hodnotu) Přetížení prefixové varianty cislo operator++(cislo & a) a.nastavhodnotu(a.vrathodnotu() + 1); return a; operand je do funkce předáván jako odkaz, ale tentokrát není konstantní, protože funkce bude měnit jeho hodnotu (zvyšovat ji o jedničku) cislo a(7), b(2); b = ++a; cout << "hodnota a je " << a.vrathodnotu() << endl; cout << "hodnota b je " << b.vrathodnotu() << endl; 16

Operátory jako běžné funkce návratová hodnota operátoru je objekt typu cislo, aby bylo možné výsledek práce operátoru přiřadit jinému objektu, tzn. aby šlo napsat b = ++a; vracený objekt se z funkce operator++ vrací hodnotou, tzn. při návratu se vytvoří jeho kopie, která je posléze přiřazena do objektu vlevo od operátoru = je tedy zbytečně volán kopírovací konstruktor, v tomto případě je účelnější předávat objekt z funkce odkazem: cislo & operator++(cislo & a) a.nastavhodnotu(a.vrathodnotu() + 1); return a; Nyní se už nepořizuje kopie vraceného objektu, vracen je přímo objekt předaný funkci jako parametr. Ten také figuruje jako pravá strana operátoru =, pokud je inkrementace spojena s přiřazením jako v případě příkazu b = ++a; 17

Operátory jako běžné funkce Přetížení postfixové varianty inkrementace aby kompilátor rozeznal o kterou variantu jde, platí úmluva, že u přetěžování postfixové varianty je funkci jako parametr navíc předáno celé číslo tento parametr bude ve funkci ignorován, jedná se jen o příznak toho, že přetěžujeme postfix cislo operator++(cislo & a, int priznak) cislo pomocne(a.vrathodnotu()); a.nastavhodnotu(a.vrathodnotu() + 1); return pomocne; Funkce nejdříve vytvoří pomocný objekt cislo se stejnou hodnotou jako předaný parametr. Potom zvýší hodnotu parametru a nakonec vrátí objekt s původní hodnotou. parametr priznak se ve funkci nepoužívá, nepoužívá se ani při aplikaci operátoru v programu: cislo a(7), b(2); b = a++; cout << endl; cout << " hodnota a je " << a.vrathodnotu() << endl; cout << " hodnota b je " << b.vrathodnotu() << endl; 18

Operátory jako běžné funkce návratovou hodnotou je opět objekt typu cislo, který ale v tomto případě musí být vracen hodnotou (s pomocí kopie) a nikoliv odkazem důvody: postfixový operátor musí změnit hodnotu parametru, ale vrací původní hodnotu (před změnou) je tedy potřeba vytvořit dočasný objekt pro uchování původní hodnoty a ten vrátit, což se musí provést hodnotou, protože dočasný objekt se po skončení funkce opustí svůj obor platnosti (předávali bychom odkaz na již neexistující objekt) 19

Pointer this každá funkce třídy má k dispozici zvláštní pointer, který obsahuje adresu objektu, se kterým funkce aktuálně pracuje, tento pointer se nazývá this následující funkce ověřuje, že pointer vždy ukazuje na aktuální objekt // členská funkce třídy cislo, ověřující hodnotu pointeru this const cislo * HodnotaThis() return this; použití funkce demonstruje, že this vždy obsahuje adresu aktuálního objektu: cislo a(7); cout << cislo a << endl; cout << adresa: << &a << endl; cout << this: << a.hodnotathis() << endl; cislo b(4); cout << cislo b << endl; cout << adresa: << &b << endl; cout << this: << b.hodnotathis() << endl; pointer this je možné využít při přetěžování operátorů (viz dále) 20

Přetížené operátory jako členské funkce Operátor inkrementace jako členská funkce // deklarace (v deklaraci třídy) cislo & operator++(); // definice cislo & cislo::operator++() ++hodnota; return *this; funkce přetěžující prefixovou variantu ++ využívá pointeru this k tomu, aby vrátila odkaz na objekt se zvýšenou hodnotou (funkce tedy vrací ten objekt, se kterým zrovna pracuje) 21

Přetížené operátory jako členské funkce Operátor sčítání jako členská funkce // deklarace (v deklaraci třídy) cislo operator+(const cislo & pravastrana); // definice cislo cislo::operator+(const cislo & pravastrana) return cislo(hodnota + pravastrana.vrathodnotu()); // použití v programu cislo a(7), b(2), c(0); c = a + b; // hodnota c je teď 9 Pozn. protože operátor + je teď členskou funkcí třídy, šel by zavolat i takto: c = a.operator+(b); 22

Přetížené operátory jako členské funkce Operátor porovnání jako členská funkce // deklarace (v deklaraci třídy) bool operator==(const cislo & pravastrana) const; // definice bool cislo::operator==(const cislo & pravastrana)const return (hodnota == pravastrana.vrathodnotu()); funkce vrací hodnotu typu bool, která informuje o tom, zda se objekty rovnají cislo a(7), b(4); if (a == b) // použití operátoru ==... pokud bychom chtěli používat operátor!=, museli bychom ho přetížit také (z přetížení == neplyne možnost automaticky použít doplňkový!=) 23

Přetížení operátoru přiřazení operátor přiřazení je ke třídě automaticky poskytován kompilátorem, můžete tedy provádět přiřazení mezi jednotlivými objekty třídy cislo a(5), b(7); a = b; cout << "hodnota a je " << a.vrathodnotu(); kompilátorem poskytnutý operátor přiřazuje hodnoty datových členů pravého objektu do datových členů levého objektu (jak by se dalo čekat) problém nastane, pokud třída uchovává pointer na data na haldě, potom při použití vestavěného operátoru dojde ke zkopírování adresy a oba objekty ukazují do stejného místa (stejná situace jako u kopírovacího konstruktoru) 5 7 5 7 cislo a hodnota cislo b hodnota a = b; cislo a hodnota cislo b hodnota v tomto případě je nutné napsat vlastní operátor 24

Přetížení operátoru přiřazení přetížený operátor = pak může vypadat např. takto: cislo & cislo::operator=(const cislo & pravastrana) *hodnota = pravastrana.vrathodnotu(); return *this; 5 7 7 7 cislo a hodnota cislo b hodnota a = b; cislo a hodnota cislo b hodnota funkce vrací objekt cislo, aby bylo možné napsat a = b = c; objekt je vracen odkazem, aby nedocházelo ke zbytečnému volání kopírovacího konstruktoru k vracení odkazem je použit pointer this 25

Poznámky k přetěžování operátorů Omezení kladená na přetěžování operátorů není možné vytvářet nové operátory není možné měnit aritu operátorů (tzn. jestli je operátor unární či binární) přetěžováním nelze změnit prioritu operátorů nelze přetížit operátory pro standardní datové typy (např. int, double...) operátory = (přiřazení), -> (nepřímý přístup přes pointer), [] (index), () (volání funkce) musí být metodami třídy 26

Konverze mezi objekty třídy a jinými datovými typy v praxi může být užitečné moci konvertovat proměnnou nějakého typu (ať už defaultního nebo objektu jiné třídy) na objekt naší třídy, případně moci provést konverzi opačnou Konverze jiný typ objekt naší třídy provádíme pomocí konstruktoru, který jako parametr přebírá proměnnou daného typu a vytvoří objekt naší třídy chceme-li umět konvertovat celočíselnou hodnotu na objekt cislo, potřebujeme konstruktor přebírající celočíselnou hodnotu: cislo(int a); s pomocí tohoto můžeme jednak vytvořit objekt: cislo a(7), ale umožní nám i toto: int x = 10; // proměnná typu int cislo c; // objekt cislo (zde např. pomocí výchozího konstruktoru) c = x; // konverze integeru x na objekt cislo Co se děje na třetím řádku? Na pravé straně operátoru = se vytvoří dočasný objekt cislo (pomocí konstruktoru přebírajícího celé číslo), tento dočasný objekt je pak přiřazen objektu c stejným způsobem lze konvertovat objekty jiných tříd na objekt cislo, vždy je nutné mít napsaný konstruktor, přebírající objekt dané třídy 27

Konverze mezi objekty třídy a jinými datovými typy Konverze objekt naší třídy jiný typ provádíme pomocí operátoru konverze deklarace operátoru konverze vypadá takto operator typ(); operátor konverze nemá návratovou hodnotu, ale ve skutečnosti vždy vrací deklarovaný typ konverze objektu cislo na int se provede takto // deklarace operator int(); // definice cislo::operator int() return hodnota; použití v programu cislo a(7); // objekt typu cislo int x = a; // konverze objektu cislo na int stejným způsobem lze konvergovat objekt cislo na objekt jiné třídy 28