Jazyk C++ I Polymorfismus AR 2013/2014 Jazyk C++ I
Operátory Co to vůbec jsou operátory? Na co je používáme? AR 2013/2014 Jazyk C++ I 2
Operátory Můžeme si upravit operátory pro vlastní objektové typy? AR 2013/2014 Jazyk C++ I 3
Operátory Můžeme si upravit operátory pro vlastní objektové typy? ANO AR 2013/2014 Jazyk C++ I 4
Operátory Každý přetížený operátor se deklaruje jako operátorová funkce se syntaxí: operator operatorsymbol; AR 2013/2014 Jazyk C++ I 5
Operátory operátorové symboly AR 2013/2014 Jazyk C++ I 6
Unární operátor Definuje se jako obyčejná funkce s jedním parametrem nebo jako metoda objektového typu bez parametru. AR 2013/2014 Jazyk C++ I 7
Binární operátor Definuje se jako obyčejná funkce se dvěma parametry nebo jako metoda objektového typu s jedním parametrem. AR 2013/2014 Jazyk C++ I 8
Volání přetížených operátorů Dva způsoby: 1. Jako původní operátor 2. Jako operátorovou funkci s parametrem v kulatých závorkách TComplexNumber sum = a + b; TComplexNumber sum = a.operator+(b); AR 2013/2014 Jazyk C++ I 9
Přetěžování operátorů - pravidla Možnost rozšíření všech definic většiny operátorů na objektové typy. Nelze vytvářet vlastní nové operátory. Nelze změnit význam operátorů pro vestavěné typy. Nelze změnit prioritu a asociativitu operátorů. Parametry operátorové funkce nemohou mít předepsané implicitní hodnoty AR 2013/2014 Jazyk C++ I 10
Přetěžování operátorů Čtyři skupiny: 1. Operátory, které nelze přetěžovat 2. Operátory, které lze přetěžovat pouze jako nestatické metody objektových typů 3. Operátory, které lze přetypovat jako obyčejné funkce nebo jako statické metody třídy. 4. Operátory, které lze přetěžovat jako nestatické metody třídy nebo jako obyčejné funkce, které mají alespoň jeden parametr objektového typu či výčtového typu AR 2013/2014 Jazyk C++ I 11
1. Skupina Operátory, které nelze přetěžovat?: Operátor podmíněného výrazu :: Rozlišovací operátor. Operátor přímé kvalifikace.* Dereferencování třídních ukazatelů sizeof dynamic_cast, static_cast, cost_cast, reinterpret_cast Operátor sizeof Operátory přetypování AR 2013/2014 Jazyk C++ I 12
4. Skupina Operátory, které lze přetěžovat jako nestatické metody třídy nebo jako obyčejné funkce, které mají alespoň jeden parametr objektového typu či výčtového typu AR 2013/2014 Jazyk C++ I 13
4. Skupina Unární operátory Lze přetížit definováním: Obyčejné funkce s jedním parametrem, Nestatické metody třídy bez parametrů. a.operator Symbol() operator Symbol(a) AR 2013/2014 Jazyk C++ I 14
4. Skupina Unární operátory class TBitKalendar { public: }; enum { PocTydnu = 52 }; uint8_t Kal[PocTydnu]; TBitKalendar() { memset(kal, 0, sizeof Kal); } TBitKalendar operator ~() const; // doplněk může //být konstantní neboť nemění //instanci, na které je volán TBitKalendar TBitKalendar::operator ~() const { TBitKalendar t; for (int i = 0; i < PocTydnu; i++) t.kal[i]= ~Kal[i]; return t; } AR 2013/2014 Jazyk C++ I 15
4. Skupina operátory ++ a -- Speciální unární operátory Lze u nich přetížit jejich prefixovou i postfixovou variantu. Prefixová varianta se přetěžuje standardně jako obyčejná funkce s jedním parametrem nebo jako metoda třídy bez parametru. Postfixová varianta se definuje jako obyčejná funkce se dvěma parametry nebo jako metoda třídy s jedním parametrem. AR 2013/2014 Jazyk C++ I 16
4. Skupina operátory ++ a -- enum TDen { pondeli, utery, streda, ctvrtek, patek, sobota, nedele }; TDen operator ++ (TDen& Den) // prefixový operátor { int d = Den + 1; return Den = (d == nedele+1)? pondeli : static_cast<tden>(d); } TDen operator ++ (TDen& Den, int) // postfixový operátor { TDen DenPuv = Den; int d = Den + 1; Den = (d == nedele+1)? pondeli : static_cast<tden>(d); return DenPuv; } AR 2013/2014 Jazyk C++ I 17
4. Skupina Binární operátory Binární operátory lze přetížit definováním: Obyčejné funkce se dvěma parametry výčtového nebo objektového typu, Nestatické metody třídy s jedním parametrem výčtového nebo objektového typu. a.operator symbol(b) operator symbol(a, b) AR 2013/2014 Jazyk C++ I 18
4. Skupina Binární operátory Přetížení binárních operátorů +, -, *, /, % neznamená přetížení jejich složitějších přiřazovacích variant. Složené přiřazovací operátory lze přetížit jako funkci i jako metody. Obyčejný přiřazovací operátor= pouze jako metodu. AR 2013/2014 Jazyk C++ I 19
4. Skupina Binární operátory class TMatice { int m, n; double **a; public: TMatice(int _n = 0, int _m = 0, double c = 0); TMatice(const TMatice& t); ~TMatice(); // násobení matice číslem TMatice operator* (const double c) const; // nemění své operandy, proto může být const } AR 2013/2014 Jazyk C++ I 20
2. Skupina Operátory, které lze přetěžovat pouze jako nestatické metody objektových typů přiřazení =, operátor indexování [], volání funkce (), nepřímé kvalifikace ->, přetypování (typ) AR 2013/2014 Jazyk C++ I 21
2. Skupina operátor přiřazení Operátor přiřazení nelze dědit. Jedná se o nestatickou metodu ve tvaru operator =(parameter) Uživatelem deklarovaný kopírovací operátor přiřazení Implicitně deklarovaný kopírovací operátor přiřazení TA& TA::operator = (const TA&); TA& TA::operator = (TA&); AR 2013/2014 Jazyk C++ I 22
2. Skupina operátor přiřazení class TMatice { TMatice& operator = (const TMatice& t); }; TMatice& TMatice::operator = (const TMatice& t) { if (this!= &t) { this->~tmatice(); m = t.m; n = t.n; a = new double*[m]; for (int i = 0; i < m; i++) { a[i] = new double[n]; memcpy(a[i], t.a[i], n*sizeof(double)); } } return *this; } AR 2013/2014 Jazyk C++ I 23
2. Skupina Operátor indexování Jedná se o nestatickou metodu ve tvaru operator [](parameter) Parametr je libovolného typu. a[i]; a.operator[](i); AR 2013/2014 Jazyk C++ I 24
2. Skupina Operátor indexování class TIntArr { int *a, n; public: TIntArr(int _n) : n(_n) { a = new int[n]; } ~TIntArr() { delete[] a; } int& operator [] (int Index); }; int& TIntArr::operator [] (int Index) { if (Index < 0 Index >= n) Chyba(); return a[index]; } AR 2013/2014 Jazyk C++ I 25
2. Skupina Operátor indexování class TIntArr2 { //... int operator [] (int Index) const; }; int TIntArr2::operator [] (int Index) const { if (Index < 0 Index >= n) Chyba(); return a[index]; } AR 2013/2014 Jazyk C++ I 26
2. Skupina operátor volání jako funkce Jedná se o nestatickou metodu mající tvar: Operator () (argumentslistoptional) a(x, y) a.operator()(x, y) AR 2013/2014 Jazyk C++ I 27
2. Skupina operátor volání jako funkce class ObsahujePodretezec { string hledany; public: ObsahujePodretezec(string hledany) : hledany(hledany) { } bool operator() (const string &pom) { return pom.find(hledany)!= string::npos; } }; AR 2013/2014 Jazyk C++ I 28
2. Skupina operátor nepřímé kvalifikace Operátor nepřímé kvalifikace -> je považován jako unární operátor. Operátor musí vracet ukazatel na třídu nebo instanci třídy, ve které je také přetížen. Přetížení pomocí nestatické metody bez parametru ve tvaru operator -> (). (a.operator ())->x; AR 2013/2014 Jazyk C++ I 29
2. Skupina operátor nepřímé kvalifikace class TAutoPtrMat { TMatice* Matice; public: TAutoPtrMat(TMatice* t) : Matice(t) {} ~TAutoPtrMat() { delete Matice; } TMatice* operator ->() { return Matice; } //... }; void f() { TAutoPtrMat A(new TMatice(5, 3, 0)); A->Vypis(); } AR 2013/2014 Jazyk C++ I 30
2. Skupina operátor přetypování Tvar operátoru je složen z klíčového slova operator, názvu typu, na který se má objektový typ konvertovat a kulatých závorek. operator char* (); operator long int (); operator TA (); AR 2013/2014 Jazyk C++ I 31
2. Skupina operátor přetypování class TB { long i; public: TB(long _i) : i(_i) {} //... }; class TA { int i; public: TA(int _i) : i(_i) {} operator TB() { return TB(i); } operator int() { return i; } }; AR 2013/2014 Jazyk C++ I 32
2. Skupina operátor přetypování TA a; f(static_cast<tb>(a)); f((tb)a); f(tb(a)); f(a); cout << A; AR 2013/2014 Jazyk C++ I 33
Zdroje PRATA, Stephen. Mistrovství v C++. 3. aktualiz. vyd. Překlad Boris Sokol. Brno: Computer Press, 2007, 1119 s. ISBN 978-80-251-1749-1. AR 2013/2014 Jazyk C++ I 34