v C++ je přetížení operátorů polymorfismus v době kompilace. Jde o myšlenku dát zvláštní význam existujícímu operátoru v C++, aniž by se změnil jeho původní význam.
V tomto článku budeme dále diskutovat o přetěžování operátorů v C++ s příklady a uvidíme, které operátory můžeme nebo nemůžeme přetížit v C++.
Přetížení operátorů C++
C++ má schopnost poskytnout operátorům speciální význam pro datový typ, tato schopnost je známá jako přetížení operátorů. Přetížení operátorů je polymorfismus v době kompilace. Například můžeme přetížit operátor „+“ ve třídě, jako je String, takže můžeme zřetězit dva řetězce pouhým použitím +. Další příklady tříd, kde mohou být aritmetické operátory přetíženy, jsou komplexní čísla, zlomková čísla, velká celá čísla atd.
Příklad:
int a; float b,sum; sum = a + b;>
Zde jsou proměnné aab typu int a float, což jsou vestavěné datové typy. Proto operátor sčítání „+“ může snadno přidat obsah a a b. Je to proto, že operátor sčítání + je předdefinován pro přidávání proměnných pouze vestavěného datového typu.
Implementace:
C++
// C++ Program to Demonstrate the> // working/Logic behind Operator> // Overloading> class> A {> >statements;> };> int> main()> {> >A a1, a2, a3;> >a3 = a1 + a2;> >return> 0;> }> |
>
>
V tomto příkladu máme 3 proměnné a1, a2 a a3 typu třídy A. Zde se pokoušíme přidat dva objekty a1 a a2, které jsou uživatelsky definovaného typu, tj. typu třídy A pomocí operátoru +. To není povoleno, protože operátor sčítání + je předdefinován tak, aby fungoval pouze s vestavěnými datovými typy. Ale zde je třída A uživatelem definovaný typ, takže kompilátor generuje chybu. Zde přichází na řadu koncept přetížení operátora.
Nyní, pokud chce uživatel přimět operátor + přidat dva objekty třídy, musí předefinovat význam operátoru + tak, aby přidal dva objekty třídy. To se provádí pomocí konceptu přetížení operátora. Takže hlavní myšlenkou přetěžování operátorů je použití operátorů C++ s proměnnými třídy nebo objekty třídy. Předefinování významu operátorů skutečně nemění jejich původní význam; místo toho jim byl dán další význam spolu s jejich stávajícími.
Příklad přetížení operátorů v C++
C++
// C++ Program to Demonstrate> // Operator Overloading> #include> using> namespace> std;> class> Complex {> private>:> >int> real, imag;> public>:> >Complex(>int> r = 0,>int> i = 0)> >{> >real = r;> >imag = i;> >}> >// This is automatically called when '+' is used with> >// between two Complex objects> >Complex operator+(Complex>const>& obj)> >{> >Complex res;> >res.real = real + obj.real;> >res.imag = imag + obj.imag;> >return> res;> >}> >void> print() { cout << real <<>' + i'> << imag <<>'
'>; }> };> int> main()> {> >Complex c1(10, 5), c2(2, 4);> >Complex c3 = c1 + c2;> >c3.print();> }> |
síť a internet
>
>Výstup
12 + i9>
Rozdíl mezi funkcemi operátora a normálními funkcemi
Funkce operátora jsou stejné jako normální funkce. Jediný rozdíl je v tom, že název funkce operátora je vždy klíčové slovo operátora následovaný symbolem operátoru a funkce operátora jsou volány při použití odpovídajícího operátoru.
Příklad
C++
#include> using> namespace> std;> class> Complex {> private>:> >int> real, imag;> public>:> >Complex(>int> r = 0,>int> i = 0)> >{> >real = r;> >imag = i;> >}> >void> print() { cout << real <<>' + i'> << imag << endl; }> >// The global operator function is made friend of this> >// class so that it can access private members> >friend> Complex operator+(Complex>const>& c1,> >Complex>const>& c2);> };> Complex operator+(Complex>const>& c1, Complex>const>& c2)> {> >return> Complex(c1.real + c2.real, c1.imag + c2.imag);> }> int> main()> {> >Complex c1(10, 5), c2(2, 4);> >Complex c3> >= c1> >+ c2;>// An example call to 'operator+'> >c3.print();> >return> 0;> }> |
>
>Výstup
12 + i9>
Můžeme přetížit všechny operátory?
Téměř všichni operátoři mohou být přetíženi kromě několika. Následuje seznam operátorů, které nelze přetížit.
sizeof typeid Scope resolution (::) Class member access operators (.(dot), .* (pointer to member operator)) Ternary or conditional (?:)>
Operátory, které lze v C++ přetížit
Můžeme přetížit
Unární operátory Binární operátory Speciální operátory ( [ ], () atd.)
Ale mezi nimi jsou někteří operátoři, které nelze přetížit. Oni jsou
Operátor rozlišení rozsahu (: Operátor výběru členů Výběr člena prostřednictvím *
Ukazatel na členskou proměnnou
- Podmíněný operátor (? Sizeof operator sizeof()
| Operátoři, kteří mohou být přetíženi | Příklady |
|---|---|
| Binární aritmetika | +, -, *, /, % |
| Unární aritmetika | +, -, ++, — |
| Úkol | =, +=,*=, /=,-=, %= |
| bitový | &, | , <> , ~ , ^ |
| De-referencování | (->) |
| Dynamická alokace paměti, Zrušení přidělení | Nové, smazat |
| Dolní index | [ ] |
| Volání funkce | () |
| Logický | &, | |, ! |
| Relační | >, <, = =, = |
Proč nemohou být výše uvedené operátory přetíženy?
1. velikost operátora
Vrátí velikost objektu nebo datového typu zadaného jako operand. To je vyhodnoceno kompilátorem a nelze jej vyhodnotit za běhu. Správné zvýšení ukazatele v poli objektů implicitně závisí na velikosti operátoru. Změna jeho významu pomocí přetížení by způsobila kolaps základní části jazyka.
2. typid operátor
To poskytuje programu CPP se schopností obnovit skutečně odvozený typ objektu, na který odkazuje ukazatel nebo odkaz. U tohoto operátora jde o to jednoznačně identifikovat typ. Pokud chceme, aby uživatelsky definovaný typ ‚vypadal‘ jako jiný typ, lze použít polymorfismus, ale význam operátoru typeid musí zůstat nezměněn, jinak by mohly nastat vážné problémy.
3. Rozlišení rozsahu (::) Operátor
To pomáhá identifikovat a specifikovat kontext, na který identifikátor odkazuje, zadáním jmenného prostoru. Je kompletně vyhodnocen za běhu a pracuje spíše s názvy než s hodnotami. Operandy rozlišení rozsahu jsou výrazy poznámek s datovými typy a CPP nemá žádnou syntaxi pro jejich zachycení v případě přetížení. Je tedy syntakticky nemožné tento operátor přetížit.
4. Operátoři přístupu členů třídy (.(tečka ), .* (ukazatel na členský operátor))
Důležitost a implicitní použití operátorů přístupu členů třídy lze pochopit z následujícího příkladu:
Příklad:
C++
// C++ program to demonstrate operator overloading> // using dot operator> #include> using> namespace> std;> class> ComplexNumber {> private>:> >int> real;> >int> imaginary;> public>:> >ComplexNumber(>int> real,>int> imaginary)> >{> >this>->skutečný = skutečný;> >this>->imaginární = imaginární;> >}> >void> print() { cout << real <<>' + i'> << imaginary; }> >ComplexNumber operator+(ComplexNumber c2)> >{> >ComplexNumber c3(0, 0);> >c3.real =>this>->real + c2.real;> >c3.imaginary =>this>->imaginární + c2.imaginární;> >return> c3;> >}> };> int> main()> {> >ComplexNumber c1(3, 5);> >ComplexNumber c2(2, 4);> >ComplexNumber c3 = c1 + c2;> >c3.print();> >return> 0;> }> |
>
>Výstup
5 + i9>
Vysvětlení:
Příkaz KomplexníČíslo c3 = c1 + c2; je interně přeloženo jako KomplexníČíslo c3 = c1.operátor+ (c2); za účelem vyvolání funkce operátora. Argument c1 je implicitně předán pomocí '.' operátor. Další příkaz také využívá operátor tečky pro přístup k členské funkci print a předání c3 jako argumentu.
Kromě toho tyto operátory také pracují se jmény a ne s hodnotami a neexistuje žádné ustanovení (syntakticky), které by je přetížilo.
5. Ternární nebo podmíněný (?:) Operátor
Ternární nebo podmíněný operátor je zkrácená reprezentace příkazu if-else. V operátoru jsou pravdivé/nepravdivé výrazy vyhodnoceny pouze na základě pravdivostní hodnoty podmíněného výrazu.
conditional statement ? expression1 (if statement is TRUE) : expression2 (else)>
Funkce přetěžující ternární operátor pro třídu řekněme ABC pomocí definice
ABC operator ?: (bool condition, ABC trueExpr, ABC falseExpr);>
by nemohl zaručit, že byl vyhodnocen pouze jeden z výrazů. Ternární operátor tedy nemůže být přetížen.
Důležité body o přetížení operátora
1) Aby přetížení operátora fungovalo, musí být alespoň jeden z operandů uživatelem definovaný objekt třídy.
2) Operátor přidělení: Kompilátor automaticky vytvoří výchozí operátor přiřazení pro každou třídu. Výchozí operátor přiřazení přiřadí všechny členy pravé strany k levé straně a ve většině případů funguje dobře (toto chování je stejné jako u konstruktoru kopírování). Další podrobnosti naleznete zde.
3) Operátor konverze: Můžeme také napsat převodní operátory, které lze použít k převodu jednoho typu na jiný typ.
Příklad:
C++
// C++ Program to Demonstrate the working> // of conversion operator> #include> using> namespace> std;> class> Fraction {> private>:> >int> num, den;> public>:> >Fraction(>int> n,>int> d)> >{> >num = n;> >den = d;> >}> >// Conversion operator: return float value of fraction> >operator>float>()>const> >{> >return> float>(num) />float>(den);> >}> };> int> main()> {> >Fraction f(2, 5);> >float> val = f;> >cout << val <<>'
'>;> >return> 0;> }> |
>
>Výstup
příkaz java case
0.4>
Přetížené konverzní operátory musí být členskou metodou. Dalšími operátory mohou být buď členská metoda, nebo globální metoda.
4) Jakýkoli konstruktor, který lze volat pomocí jediného argumentu, funguje jako konstruktor převodu, což znamená, že jej lze použít také pro implicitní převod na konstruovanou třídu.
Příklad:
C++
// C++ program to demonstrate can also be used for implicit> // conversion to the class being constructed> #include> using> namespace> std;> class> Point {> private>:> >int> x, y;> public>:> >Point(>int> i = 0,>int> j = 0)> >{> >x = i;> >y = j;> >}> >void> print()> >{> >cout <<>'x = '> << x <<>', y = '> << y <<>'
'>;> >}> };> int> main()> {> >Point t(20, 20);> >t.print();> >t = 30;>// Member x of t becomes 30> >t.print();> >return> 0;> }> |
>
>Výstup
x = 20, y = 20 x = 30, y = 0>
Kvíz o přetížení operátora