v C++ je preťaženie operátora polymorfizmus počas kompilácie. Ide o myšlienku prisúdenia špeciálneho významu existujúcemu operátorovi v C++ bez toho, aby sa zmenil jeho pôvodný význam.
V tomto článku budeme ďalej diskutovať o preťažení operátorov v C++ s príkladmi a uvidíme, ktoré operátory môžeme alebo nemôžeme preťažiť v C++.
Preťaženie operátora C++
C++ má schopnosť poskytnúť operátorom špeciálny význam pre dátový typ, táto schopnosť je známa ako preťaženie operátorov. Preťaženie operátora je polymorfizmus v čase kompilácie. Napríklad môžeme preťažiť operátor „+“ v triede, ako je String, aby sme mohli zreťaziť dva reťazce iba pomocou +. Ďalšie príklady tried, kde môžu byť aritmetické operátory preťažené, sú komplexné čísla, zlomkové čísla, veľké celé čísla atď.
Príklad:
int a; float b,sum; sum = a + b;>
Tu sú premenné a a b typu int a float, čo sú vstavané dátové typy. Preto operátor sčítania „+“ môže ľahko pridať obsah a a b. Je to preto, že operátor sčítania + je preddefinovaný na pridávanie len premenných vstavaného dátového typu.
Implementácia:
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 príklade máme 3 premenné a1, a2 a a3 typu triedy A. Tu sa snažíme pridať dva objekty a1 a a2, ktoré sú užívateľsky definovaného typu, teda typu triedy A pomocou operátora +. Toto nie je povolené, pretože operátor sčítania + je preddefinovaný tak, aby fungoval iba so vstavanými typmi údajov. Ale tu je trieda A užívateľsky definovaný typ, takže kompilátor vygeneruje chybu. Tu prichádza na scénu koncept preťaženia operátora.
Teraz, ak chce používateľ prinútiť operátor + pridať dva objekty triedy, musí predefinovať význam operátora + tak, že pridá dva objekty triedy. To sa vykonáva pomocou konceptu preťaženia operátora. Takže hlavnou myšlienkou preťaženia operátorov je použitie operátorov C++ s premennými triedy alebo objektmi triedy. Predefinovanie významu operátorov skutočne nemení ich pôvodný význam; namiesto toho im bol priradený ďalší význam spolu s ich existujúcimi.
Príklad preťaženia operátora v C++
C++
zoradiť zoznam polí
// 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();> }> |
>
>Výkon
12 + i9>
Rozdiel medzi funkciami operátora a normálnymi funkciami
Funkcie operátora sú rovnaké ako bežné funkcie. Jediný rozdiel je v tom, že názov funkcie operátora je vždy kľúčové slovo operátora nasleduje symbol operátora a funkcie operátora sa volajú, keď sa použije zodpovedajúci operátor.
Prí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;> }> |
>
>
java tutoriályVýkon
12 + i9>
Môžeme preťažiť všetkých operátorov?
Takmer všetci operátori môžu byť preťažení okrem niekoľkých. Nasleduje zoznam operátorov, ktorých nemožno preťažiť.
sizeof typeid Scope resolution (::) Class member access operators (.(dot), .* (pointer to member operator)) Ternary or conditional (?:)>
Operátory, ktoré môžu byť preťažené v C++
Môžeme sa preťažiť
Unárne operátory Binárne operátory Špeciálne operátory ( [ ], () atď.)
Medzi nimi sú však niektorí operátori, ktorých nemožno preťažiť. Oni sú
Operátor rozlíšenia rozsahu (: operátor výberu člena Výber člena cez *
Ukazovateľ na členskú premennú
- Podmienený operátor (? Sizeof operator sizeof()
| Operátori, ktorí môžu byť preťažení | Príklady |
|---|---|
| Binárna aritmetika | +, -, *, /, % |
| Unárna aritmetika | +, -, ++, — |
| Pridelenie | =, +=,*=, /=,-=, %= |
| Bitovo | &, | , <> , ~ , ^ |
| De-referencovanie | (->) |
| Dynamická alokácia pamäte, Zrušenie pridelenia | Nové, vymazať |
| Dolný index | [ ] |
| Volanie funkcie | () |
| Logické | &, | |, ! |
| Relačný | >, <, = =, = |
Prečo nemôžu byť vyššie uvedené operátory preťažené?
1. veľkosť operátora
Toto vráti veľkosť objektu alebo údajového typu zadaného ako operand. Toto vyhodnocuje kompilátor a nedá sa vyhodnotiť počas behu. Správne zvyšovanie ukazovateľa v poli objektov implicitne závisí od veľkosti operátora. Zmena jeho významu pomocou preťaženia by spôsobila kolaps základnej časti jazyka.
2. typid operátor
To poskytuje programu CPP so schopnosťou obnoviť skutočne odvodený typ objektu, na ktorý odkazuje ukazovateľ alebo odkaz. Pre tohto operátora ide o jedinečnú identifikáciu typu. Ak chceme, aby používateľom definovaný typ „vyzeral“ ako iný typ, možno použiť polymorfizmus, ale význam operátora typid musí zostať nezmenený, inak by mohli vzniknúť vážne problémy.
3. Rozlíšenie rozsahu (::) Operátor
To pomáha identifikovať a špecifikovať kontext, na ktorý identifikátor odkazuje, zadaním menného priestoru. Kompletne sa vyhodnocuje za behu a funguje skôr na menách ako na hodnotách. Operandy rozlíšenia rozsahu sú výrazy poznámok s typmi údajov a CPP nemá žiadnu syntax na ich zachytenie, ak by bol preťažený. Takže je syntakticky nemožné preťažiť tento operátor.
4. Operátory prístupu členov triedy (.(bodka ), .* (ukazovateľ na operátora člena))
Dôležitosť a implicitné použitie operátorov prístupu členov triedy možno pochopiť na nasledujúcom príklade:
Príklad:
C++
java inicializovať pole
// 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>->skutočný = skutočný;> >this>->imaginárny = imaginárny;> >}> >void> print() { cout << real <<>' + i'> << imaginary; }> >ComplexNumber operator+(ComplexNumber c2)> >{> >ComplexNumber c3(0, 0);> >c3.real =>this>->real + c2.real;> >c3.imaginary =>this>->imaginárny + c2.imaginárny;> >return> c3;> >}> };> int> main()> {> >ComplexNumber c1(3, 5);> >ComplexNumber c2(2, 4);> >ComplexNumber c3 = c1 + c2;> >c3.print();> >return> 0;> }> |
>
>Výkon
5 + i9>
Vysvetlenie:
Príkaz Komplexné číslo c3 = c1 + c2; sa interne prekladá ako KomplexnéČíslo c3 = c1.operátor+ (c2); aby ste vyvolali funkciu operátora. Argument c1 je implicitne odovzdaný pomocou '.' operátor. Ďalší príkaz tiež využíva bodkový operátor na prístup k členskej funkcii print a odovzdanie c3 ako argument.
Okrem toho tieto operátory pracujú aj na menách a nie na hodnotách a neexistuje žiadne ustanovenie (syntakticky) na ich preťaženie.
5. Ternárny alebo podmienený (?:) Operátor
Ternárny alebo podmienený operátor je skrátenou reprezentáciou príkazu if-else. V operátore sú pravdivé/nepravdivé výrazy hodnotené len na základe pravdivostnej hodnoty podmieneného výrazu.
conditional statement ? expression1 (if statement is TRUE) : expression2 (else)>
Funkcia preťažujúca ternárny operátor pre triedu povedzme ABC pomocou definície
ABC operator ?: (bool condition, ABC trueExpr, ABC falseExpr);>
by nedokázal zaručiť, že bol vyhodnotený iba jeden z výrazov. Ternárny operátor teda nemôže byť preťažený.
Dôležité body o preťažení operátora
1) Aby preťaženie operátora fungovalo, aspoň jeden z operandov musí byť užívateľom definovaný objekt triedy.
2) Operátor pridelenia: Kompilátor automaticky vytvorí predvolený operátor priradenia pre každú triedu. Predvolený operátor priradenia priraďuje všetkých členov pravej strany k ľavej strane a vo väčšine prípadov funguje dobre (toto správanie je rovnaké ako pri konštruktore kopírovania). Ďalšie podrobnosti nájdete v tejto časti.
3) Operátor konverzie: Môžeme tiež napísať konverzné operátory, ktoré možno použiť na konverziu jedného typu na iný typ.
Príklad:
C++
vkladanie triediť java
// 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ýkon
0.4>
Preťažené operátory konverzie musia byť členskou metódou. Ďalšími operátormi môžu byť buď členská metóda, alebo globálna metóda.
4) Akýkoľvek konštruktor, ktorý možno volať pomocou jediného argumentu, funguje ako konverzný konštruktor, čo znamená, že ho možno použiť aj na implicitnú konverziu na konštruovanú triedu.
Prí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ýkon
x = 20, y = 20 x = 30, y = 0>
Kvíz o preťažení operátora