C++ operatoriaus perkrova yra kompiliavimo laiko polimorfizmas. Tai idėja suteikti ypatingą reikšmę esamam operatoriui C++, nekeičiant jo pradinės reikšmės.
Šiame straipsnyje toliau aptarsime operatoriaus perkrovą C++ su pavyzdžiais ir pamatysime, kuriuos operatorius galime arba negalime perkrauti C++.
C++ operatoriaus perkrova
C++ turi galimybę suteikti operatoriams ypatingą reikšmę duomenų tipui, ši galimybė žinoma kaip operatoriaus perkrova. Operatoriaus perkrova yra kompiliavimo laiko polimorfizmas. Pavyzdžiui, galime perkrauti operatorių „+“ klasėje, pvz., String, kad galėtume sujungti dvi eilutes tiesiog naudodami +. Kiti pavyzdžiai, kur aritmetiniai operatoriai gali būti perkrauti, yra kompleksiniai skaičiai, trupmeniniai skaičiai, dideli sveikieji skaičiai ir kt.
Pavyzdys:
int a; float b,sum; sum = a + b;>
Čia kintamieji a ir b yra int ir float tipų, kurie yra integruoti duomenų tipai. Taigi pridėjimo operatorius „+“ gali lengvai pridėti a ir b turinį. Taip yra todėl, kad pridėjimo operatorius + yra iš anksto nustatytas pridėti tik įtaisytųjų duomenų tipo kintamuosius.
Įgyvendinimas:
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;> }> |
>
>
Šiame pavyzdyje turime 3 A klasės kintamuosius a1, a2 ir a3. Čia bandome pridėti du objektus a1 ir a2, kurie yra vartotojo apibrėžto tipo, t. y. A tipo, naudojant operatorių +. Tai neleidžiama, nes pridėjimo operatorius + yra iš anksto nustatytas veikti tik su integruotais duomenų tipais. Tačiau čia A klasė yra vartotojo nustatytas tipas, todėl kompiliatorius sukuria klaidą. Čia atsiranda operatoriaus perkrovos koncepcija.
Dabar, jei vartotojas nori, kad operatorius + pridėtų du klasės objektus, vartotojas turi iš naujo apibrėžti operatoriaus + reikšmę, kad jis pridėtų du klasės objektus. Tai atliekama naudojant operatoriaus perkrovos koncepciją. Taigi pagrindinė operatoriaus perkrovimo idėja yra naudoti C++ operatorius su klasės kintamaisiais arba klasės objektais. Iš naujo apibrėžus operatorių reikšmę, jų pirminė reikšmė tikrai nepakeičiama; vietoj to jiems buvo suteikta papildoma reikšmė kartu su esamomis.
Operatoriaus perkrovos pavyzdys C++
C++
dvejetainė paieškos python
// 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();> }> |
>
>Išvestis
12 + i9>
Skirtumas tarp operatoriaus funkcijų ir įprastų funkcijų
Operatoriaus funkcijos yra tokios pačios kaip ir įprastos funkcijos. Vieninteliai skirtumai yra tai, kad operatoriaus funkcijos pavadinimas visada yra operatoriaus raktažodis po jo yra operatoriaus simbolis, o operatoriaus funkcijos iškviečiamos, kai naudojamas atitinkamas operatorius.
Pavyzdys
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;> }> |
>
>Išvestis
12 + i9>
Ar galime perkrauti visus operatorius?
Beveik visi operatoriai gali būti perkrauti, išskyrus keletą. Toliau pateikiamas operatorių, kurių negalima perkrauti, sąrašas.
sizeof typeid Scope resolution (::) Class member access operators (.(dot), .* (pointer to member operator)) Ternary or conditional (?:)>
Operatoriai, kuriuos galima perkrauti C++
Galime perkrauti
Vienanariai operatoriai Dvejetainiai operatoriai Specialieji operatoriai ( [ ], () ir tt)
Tačiau tarp jų yra keletas operatorių, kurių negalima perkrauti. Jie yra
Apimties sprendimo operatorius (: narių atrankos operatorius Narių pasirinkimas per *
Rodyklė į nario kintamąjį
- Sąlyginis operatorius (? Sizeof operator sizeof()
| Operatoriai, kurie gali būti perkrauti | Pavyzdžiai |
|---|---|
| Dvejetainė aritmetika | +, -, *, /, % |
| Vienareikšmė aritmetika | +, -, ++, — |
| Užduotis | =, +=,*=, /=,-=, %= |
| Bitiškai | &, | , <> , ~ , ^ |
| Nuorodų panaikinimas | (->) |
| Dinaminis atminties paskirstymas, Paskirstymo panaikinimas | Nauja, ištrinti |
| Pradinis indeksas | [ ] |
| Funkcijos skambutis | () |
| Logiška | &, | |, ! |
| Santykinis | >, <, = =, = |
Kodėl aukščiau minėti operatoriai negali būti perkrauti?
1. operatoriaus dydis
Tai grąžina objekto arba duomenų tipo dydį, įvestą kaip operandą. Tai įvertina kompiliatorius ir jo negalima įvertinti vykdymo metu. Tinkamas žymeklio padidinimas objektų masyve netiesiogiai priklauso nuo operatoriaus dydžio. Pakeitus jo prasmę naudojant perkrovą, pagrindinė kalbos dalis sugrius.
2. typeid Operatorius
Tai suteikia CPP programai galimybę atkurti faktiškai išvestą objekto tipą, nurodytą žymekliu ar nuoroda. Šiam operatoriui svarbiausia yra unikaliai identifikuoti tipą. Jei norime, kad vartotojo apibrėžtas tipas „atrodytų“ kaip kitas tipas, galima naudoti polimorfizmą, tačiau tipo operatoriaus reikšmė turi likti nepakitusi, kitaip gali kilti rimtų problemų.
3. Apimties raiška (::) Operatorius
Tai padeda nustatyti ir nurodyti kontekstą, į kurį nurodo identifikatorius, nurodant vardų erdvę. Jis visiškai įvertinamas vykdymo metu ir veikia pagal pavadinimus, o ne į vertybes. Apimties skiriamosios gebos operandai yra pastabų išraiškos su duomenų tipais, o CPP neturi sintaksės, kuri juos užfiksuotų, jei būtų perkrauta. Taigi sintaksiškai neįmanoma perkrauti šio operatoriaus.
4. Klasės narių prieigos operatoriai (.(taškas ), .* (rodiklis į nario operatorių))
Klasės narių prieigos operatorių svarbą ir numanomą naudojimą galima suprasti per šį pavyzdį:
Pavyzdys:
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>->tikras = tikras;> >this>->įsivaizduojamas = įsivaizduojamas;> >}> >void> print() { cout << real <<>' + i'> << imaginary; }> >ComplexNumber operator+(ComplexNumber c2)> >{> >ComplexNumber c3(0, 0);> >c3.real =>this>->real + c2.real;> >c3.imaginary =>this>->imaginary + c2.imaginary;> >return> c3;> >}> };> int> main()> {> >ComplexNumber c1(3, 5);> >ComplexNumber c2(2, 4);> >ComplexNumber c3 = c1 + c2;> >c3.print();> >return> 0;> }> |
>
>Išvestis
5 + i9>
Paaiškinimas:
Teiginys ComplexNumber c3 = c1 + c2; viduje išverstas kaip Kompleksinis skaičius c3 = c1.operatorius+ (c2); operatoriaus funkcijai iškviesti. Argumentas c1 netiesiogiai perduodamas naudojant '.' operatorius. Kitame teiginyje taip pat naudojamas taško operatorius, norint pasiekti nario funkciją spausdinti ir perduoti c3 kaip argumentą.
Be to, šie operatoriai taip pat dirba su pavadinimais, o ne su reikšmėmis ir nėra nuostatos (sintaksiškai) juos perkrauti.
5. Trečias arba sąlyginis (?:) operatorius
Trečias arba sąlyginis operatorius yra trumpas if-else teiginio vaizdas. Operatoriuje teisingos / klaidingos išraiškos įvertinamos tik remiantis sąlyginės išraiškos tiesos verte.
conditional statement ? expression1 (if statement is TRUE) : expression2 (else)>
Funkcija, perkraunanti trinarį klasės operatorių, tarkime, ABC, naudodama apibrėžimą
ABC operator ?: (bool condition, ABC trueExpr, ABC falseExpr);>
negalėtų garantuoti, kad buvo įvertinta tik viena iš posakių. Taigi trijų dalių operatorius negali būti perkrautas.
Svarbūs punktai apie operatoriaus perkrovą
1) Kad operatoriaus perkrova veiktų, bent vienas iš operandų turi būti vartotojo apibrėžtas klasės objektas.
2) Priskyrimo operatorius: Kompiliatorius automatiškai sukuria numatytąjį priskyrimo operatorių kiekvienai klasei. Numatytasis priskyrimo operatorius priskiria visus dešinės pusės narius kairiajai pusei ir daugeliu atvejų veikia gerai (šis elgesys yra toks pat, kaip kopijavimo konstruktorius). Daugiau informacijos rasite čia.
3) Konversijos operatorius: Taip pat galime parašyti konvertavimo operatorius, kuriais galima konvertuoti vieną tipą į kitą.
poeilutės funkcija java
Pavyzdys:
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;> }> |
>
>Išvestis
0.4>
Perkrauti konvertavimo operatoriai turi būti nario metodas. Kiti operatoriai gali būti nario metodas arba visuotinis metodas.
4) Bet kuris konstruktorius, kurį galima iškviesti vienu argumentu, veikia kaip konvertavimo konstruktorius, o tai reiškia, kad jis taip pat gali būti naudojamas netiesioginiam konvertavimui į kuriamą klasę.
Pavyzdys:
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;> }> |
>
>Išvestis
x = 20, y = 20 x = 30, y = 0>
Viktorina apie operatoriaus perkrovą