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
Operátor sizeof
dynamic_cast, static_cast, cost_cast, reinterpret_cast
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 { enum { PocTydnu = 52 }; uint8_t Kal[PocTydnu]; public: 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
(d); } TDen operator ++ (TDen& Den, int) // postfixový operátor { TDen DenPuv = Den; int d = Den + 1; Den = (d == nedele+1) ? pondeli : static_cast(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(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