logo

Operaattorin ylikuormitus C++:ssa

C++:ssa operaattorin ylikuormitus on käännösajan polymorfismi. Se on ajatus antaa erityinen merkitys olemassa olevalle operaattorille C++:ssa muuttamatta sen alkuperäistä merkitystä.

Tässä artikkelissa keskustelemme edelleen operaattorin ylikuormituksesta C++:ssa esimerkkien avulla ja katsomme, mitä operaattoreita voimme tai emme voi ylikuormittaa C++:ssa.



C++ -operaattorin ylikuormitus

C++:lla on kyky tarjota operaattoreille erityinen merkitys tietotyypille, tämä ominaisuus tunnetaan operaattorin ylikuormituksena. Operaattorin ylikuormitus on käännösajan polymorfismi. Voimme esimerkiksi ylikuormittaa operaattoria '+' luokassa, kuten String, jotta voimme ketjuttaa kaksi merkkijonoa käyttämällä vain +. Muita esimerkkiluokkia, joissa aritmeettiset operaattorit voivat olla ylikuormitettuja, ovat kompleksiluvut, murtoluvut, suuret kokonaisluvut jne.

avaa asetusvalikko

Esimerkki:

int a; float b,sum; sum = a + b;>

Tässä muuttujat a ja b ovat tyyppejä int ja float, jotka ovat sisäänrakennettuja tietotyyppejä. Näin ollen summausoperaattori '+' voi helposti lisätä a:n ja b:n sisällön. Tämä johtuu siitä, että summausoperaattori + on ennalta määritetty lisäämään vain sisäänrakennetun tietotyypin muuttujia.



Toteutus:

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;> }>

>

>

Tässä esimerkissä meillä on 3 muuttujaa a1, a2 ja a3, joiden tyyppi on luokka A. Tässä yritämme lisätä kaksi objektia a1 ja a2, jotka ovat käyttäjän määrittämää tyyppiä eli tyyppiä A käyttämällä +-operaattoria. Tämä ei ole sallittua, koska lisäysoperaattori + on ennalta määritetty toimimaan vain sisäänrakennetuilla tietotyypeillä. Mutta tässä luokka A on käyttäjän määrittelemä tyyppi, joten kääntäjä tuottaa virheen. Tässä tulee esiin käyttäjän ylikuormituksen käsite.

Nyt, jos käyttäjä haluaa saada operaattorin + lisäämään kaksi luokkaobjektia, käyttäjän on määritettävä +-operaattorin merkitys uudelleen siten, että se lisää kaksi luokkaobjektia. Tämä tehdään käyttämällä operaattorin ylikuormituksen käsitettä. Joten pääidea Operatorin ylikuormituksen takana on käyttää C++-operaattoreita luokkamuuttujien tai luokkaobjektien kanssa. Operaattoreiden merkityksen uudelleenmäärittely ei todellakaan muuta niiden alkuperäistä merkitystä; sen sijaan niille on annettu lisämerkityksiä olemassa olevien kanssa.

Esimerkki operaattorin ylikuormituksesta C++:ssa

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();> }>

>

>

Lähtö

12 + i9>

Ero käyttäjän toimintojen ja normaalien toimintojen välillä

Käyttäjän toiminnot ovat samat kuin normaalit toiminnot. Ainoat erot ovat, että operaattorifunktion nimi on aina operaattorin avainsana seuraa operaattorin symboli, ja operaattoritoimintoja kutsutaan, kun vastaavaa operaattoria käytetään.

Esimerkki

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;> }>

>

>

Lähtö

12 + i9>

Voimmeko ylikuormittaa kaikkia operaattoreita?

Melkein kaikki operaattorit voivat ylikuormittua muutamaa lukuun ottamatta. Seuraavassa on luettelo operaattoreista, joita ei voi ylikuormittaa.

sizeof typeid Scope resolution (::) Class member access operators (.(dot), .* (pointer to member operator)) Ternary or conditional (?:)>

Operaattorit, jotka voidaan ylikuormittaa C++:ssa

Voimme ylikuormittaa

    Yksittäiset operaattorit Binäärioperaattorit Erikoisoperaattorit ( [ ], () jne)

Mutta niiden joukossa on joitain operaattoreita, joita ei voida ylikuormittaa. He ovat

    Laajuusratkaisuoperaattori (: Jäsenvalintaoperaattori Jäsenvalinta *

Osoitin jäsenmuuttujaan

    Ehdollinen operaattori (? Sizeof operator sizeof()
Operaattorit, jotka voivat olla ylikuormitettuja Esimerkkejä
Binääriaritmetiikka +, -, *, /, %
Yksinäinen aritmetiikka +, -, ++, —
Tehtävä =, +=,*=, /=,-=, %=
Bitittain &, | , <> , ~ , ^
Viittausten poistaminen (->)
Dynaaminen muistin varaus,
Varauksen purkaminen
Uusi, poista
Alaindeksi [ ]
Toimintokutsu ()
Looginen &, | |, !
Suhteellisia >, <, = =, =

Miksi yllä mainittuja operaattoreita ei voida ylikuormittaa?

1. Operaattorin koko

Tämä palauttaa operandiksi syötetyn objektin tai tietotyypin koon. Kääntäjä arvioi tämän, eikä sitä voida arvioida ajon aikana. Osoittimen oikea lisäys objektijoukossa riippuu implisiittisesti operaattorin koosta. Sen merkityksen muuttaminen ylikuormituksella aiheuttaisi kielen perusosan romahtamisen.

2. typeid Operaattori

Tämä tarjoaa CPP-ohjelmalle mahdollisuuden palauttaa osoittimen tai viitteen viittaaman kohteen tosiasiallisesti johdetun tyypin. Tämän operaattorin tarkoitus on yksilöidä tyyppi. Jos haluamme saada käyttäjän määrittämän tyypin 'näyttämään' toiselta tyypiltä, ​​voidaan käyttää polymorfiaa, mutta tyyppi-operaattorin merkityksen tulee pysyä muuttumattomana, muuten voi syntyä vakavia ongelmia.

3. Scope-resoluutio (::) Operaattori

Tämä auttaa tunnistamaan ja määrittämään kontekstin, johon tunniste viittaa, määrittämällä nimiavaruuden. Se on täysin arvioitu ajon aikana ja toimii nimien eikä arvojen perusteella. Laajuusresoluution operandit ovat tietotyyppejä sisältäviä nuottilausekkeita, eikä CPP:llä ole syntaksia niiden sieppaamiseksi, jos se olisi ylikuormitettu. Joten on syntaktisesti mahdotonta ylikuormittaa tätä operaattoria.

4. Luokan jäsenten pääsyoperaattorit (.(piste ), .* (osoitin jäsenoperaattoriin))

Luokan jäsenten pääsyoperaattoreiden tärkeys ja implisiittinen käyttö voidaan ymmärtää seuraavan esimerkin avulla:

Esimerkki:

nat vs sänky

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>->todellinen = todellinen;> >this>->kuvitteellinen = kuvitteellinen;> >}> >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;> }>

>

>

Lähtö

5 + i9>

Selitys:

Lause ComplexNumber c3 = c1 + c2; on sisäisesti käännetty Kompleksinumeroksi c3 = c1.operaattori+ (c2); operaattoritoiminnon käynnistämiseksi. Argumentti c1 välitetään implisiittisesti käyttämällä '.' operaattori. Seuraava lause käyttää myös pisteoperaattoria päästäkseen jäsenfunktioon print ja välittää c3 argumenttina.

Lisäksi nämä operaattorit käyttävät myös nimiä eivätkä arvoja, eikä niitä ole (syntaktisesti) ylikuormitettu.

5. Kolmiosainen tai ehdollinen (?:) Operaattori

Kolmiosainen tai ehdollinen operaattori on lyhennetty esitys if-else-lauseesta. Operaattorissa tosi/epätosi-lausekkeet arvioidaan vain ehdollisen lausekkeen totuusarvon perusteella.

conditional statement ? expression1 (if statement is TRUE) : expression2 (else)>

Funktio, joka ylikuormittaa luokan kolmiosaisen operaattorin, sano ABC määritelmän avulla

ABC operator ?: (bool condition, ABC trueExpr, ABC falseExpr);>

ei pystyisi takaamaan, että vain yksi lausekkeista arvioitiin. Näin ollen kolmiosaista operaattoria ei voi ylikuormittaa.

Tärkeitä tietoja käyttäjän ylikuormituksesta

1) Jotta operaattorin ylikuormitus toimisi, ainakin yhden operandeista on oltava käyttäjän määrittämä luokkaobjekti.

2) Tehtäväoperaattori: Kääntäjä luo automaattisesti oletusarvoisen tehtäväoperaattorin jokaiselle luokalle. Oletusarvoinen määritysoperaattori määrittää kaikki oikean puolen jäsenet vasemmalle puolelle ja toimii hyvin useimmissa tapauksissa (tämä toiminta on sama kuin kopioinnin rakentaja). Katso tästä lisätietoja.

3) Muunnosoperaattori: Voimme myös kirjoittaa muunnosoperaattoreita, joilla voidaan muuntaa yksi tyyppi toiseksi.

Esimerkki:

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;> }>

>

>

Lähtö

teelusikallisen kokoinen
0.4>

Ylikuormitettujen muunnosoperaattoreiden on oltava jäsenmenetelmä. Muut operaattorit voivat olla joko jäsenmenetelmä tai globaali menetelmä.

4) Mikä tahansa konstruktori, jota voidaan kutsua yhdellä argumentilla, toimii muunnoskonstruktorina, mikä tarkoittaa, että sitä voidaan käyttää myös implisiittiseen muuntamiseen rakennettavaan luokkaan.

Esimerkki:

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;> }>

>

>

Lähtö

x = 20, y = 20 x = 30, y = 0>

Tietovisa käyttäjän ylikuormituksesta