logo

Preobremenitev operaterja v C++

v C++ je preobremenitev operaterja polimorfizem v času prevajanja. Gre za zamisel o dajanju posebnega pomena obstoječemu operatorju v C++ brez spreminjanja njegovega prvotnega pomena.

izberite več tabel sql

V tem članku bomo nadalje razpravljali o preobremenitvi operatorjev v C++ s primeri in videli, katere operatorje lahko ali ne moremo preobremeniti v C++.



Preobremenitev operaterja C++

C++ ima možnost, da operaterjem zagotovi poseben pomen za tip podatkov, ta zmožnost je znana kot preobremenitev operaterja. Preobremenitev operaterja je polimorfizem v času prevajanja. Na primer, lahko preobremenimo operator '+' v razredu, kot je String, tako da lahko združimo dva niza samo z uporabo +. Drugi primeri razredov, kjer so lahko aritmetični operatorji preobremenjeni, so kompleksna števila, ulomka, velika cela števila itd.

primer:

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

Tu sta spremenljivki a in b tipa int in float, ki sta vgrajena podatkovna tipa. Zato lahko operator seštevanja '+' zlahka doda vsebino a in b. To je zato, ker je operator dodajanja + vnaprej določen za dodajanje samo spremenljivk vgrajenega podatkovnega tipa.



Izvedba:

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 tem primeru imamo 3 spremenljivke a1, a2 in a3 razreda tipa A. Tukaj poskušamo dodati dva predmeta a1 in a2, ki sta uporabniško definiranega tipa, tj. razreda tipa A z uporabo operatorja +. To ni dovoljeno, ker je operator dodajanja + vnaprej določen za delovanje samo na vgrajenih podatkovnih vrstah. Toda tukaj je razred A uporabniško določen tip, zato prevajalnik ustvari napako. Tukaj nastopi koncept preobremenitve operaterja.

Zdaj, če želi uporabnik narediti, da operator + doda dva predmeta razreda, mora uporabnik na novo definirati pomen operatorja +, tako da doda dva predmeta razreda. To se naredi z uporabo koncepta preobremenitve operaterja. Torej je glavna ideja preobremenitve operaterjev uporaba operatorjev C++ s spremenljivkami razreda ali predmeti razreda. Ponovno definiranje pomena operatorjev res ne spremeni njihovega prvotnega pomena; namesto tega so dobili dodaten pomen skupaj z obstoječimi.

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

>

>

Izhod

12 + i9>

Razlika med funkcijami operaterja in običajnimi funkcijami

Funkcije operaterja so enake običajnim funkcijam. Edina razlika je, da je ime operatorske funkcije vedno ključna beseda operaterja ki mu sledi simbol operatorja, operatorske funkcije pa se kličejo, ko je uporabljen ustrezen operator.

Primer

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

>

>

Izhod

12 + i9>

Ali lahko preobremenimo vse operaterje?

Skoraj vsi operaterji so lahko preobremenjeni, razen nekaj. Sledi seznam operaterjev, ki jih ni mogoče preobremeniti.

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

Operatorji, ki jih je mogoče preobremeniti v C++

Lahko se preobremenimo

    Unarni operatorji Binarni operatorji Posebni operatorji ( [ ], () itd.)

Toda med njimi je nekaj operaterjev, ki jih ni mogoče preobremeniti. So

kaj je 10 od 100
    Operator za razrešitev obsega (: operator za izbiro člana Izbira člana prek *

Kazalec na spremenljivko člana

    Pogojni operator (? Sizeof operator sizeof()
Operatorji, ki jih je mogoče preobremeniti Primeri
Binarna aritmetika +, -, *, /, %
Unarna aritmetika +, -, ++, —
Dodelitev =, +=,*=, /=,-=, %=
Bitno &, | , <> , ~ , ^
De-referenciranje (->)
dinamično dodeljevanje pomnilnika,
Dealokacija
Novo, izbriši
indeks [ ]
Klic funkcije ()
Logično &, | |, !
Relacijska >, <, = =, =

Zakaj zgoraj navedenih operaterjev ni mogoče preobremeniti?

1. velikost operaterja

To vrne velikost predmeta ali podatkovnega tipa, vnesenega kot operand. To ovrednoti prevajalnik in ga ni mogoče ovrednotiti med izvajanjem. Pravilno povečevanje kazalca v nizu predmetov je implicitno odvisno od operatorja sizeof. Spreminjanje njegovega pomena s preobremenitvijo bi povzročilo propad temeljnega dela jezika.

2. operator typeid

To omogoča programu CPP, da obnovi dejansko izpeljano vrsto predmeta, na katerega se sklicuje kazalec ali sklic. Bistvo tega operaterja je enolična identifikacija vrste. Če želimo, da je uporabniško določen tip 'izgledal' kot drug tip, lahko uporabimo polimorfizem, vendar mora pomen operatorja typeid ostati nespremenjen, sicer lahko pride do resnih težav.

3. Operator razrešitve obsega (::).

To pomaga identificirati in določiti kontekst, na katerega se nanaša identifikator, tako da podate imenski prostor. V celoti je ovrednoten med izvajanjem in deluje na imenih in ne na vrednostih. Operandi razrešitve obsega so notni izrazi s tipi podatkov in CPP nima sintakse za njihov zajem, če bi bil preobremenjen. Zato je sintaktično nemogoče preobremeniti ta operator.

4. Operatorji za dostop članov razreda (.(pika ), .* (kazalec na operatorja člana))

Pomen in implicitno uporabo operaterjev za dostop članov razreda je mogoče razumeti skozi naslednji primer:

primer:

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>->resnično = resnično;> >this>->namišljeno = namišljeno;> >}> >void> print() { cout << real <<>' + i'> << imaginary; }> >ComplexNumber operator+(ComplexNumber c2)> >{> >ComplexNumber c3(0, 0);> >c3.real =>this>->real + c2.real;> >c3.imaginary =>this>->namišljeno + c2.namišljeno;> >return> c3;> >}> };> int> main()> {> >ComplexNumber c1(3, 5);> >ComplexNumber c2(2, 4);> >ComplexNumber c3 = c1 + c2;> >c3.print();> >return> 0;> }>

>

>

Izhod

5 + i9>

Pojasnilo:

Stavek KompleksnoŠtevilo c3 = c1 + c2; je interno prevedeno kot kompleksno število c3 = c1.operator+ (c2); za priklic funkcije operaterja. Argument c1 je implicitno posredovan z uporabo '.' operater. Naslednji stavek prav tako uporablja operator pike za dostop do članske funkcije print in posreduje c3 kot argument.

Poleg tega ti operaterji delujejo tudi na imenih in ne na vrednostih in ni določbe (sintaktično), ki bi jih preobremenila.

5. Ternarni ali pogojni (?:) operator

Ternarni ali pogojni operator je skrajšana predstavitev stavka if-else. V operatorju se izrazi true/false ovrednotijo ​​samo na podlagi vrednosti resnice pogojnega izraza.

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

Funkcija, ki preobremeni ternarni operator za razred, recimo ABC, z uporabo definicije

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

ne bi mogel zagotoviti, da je bil ovrednoten samo eden od izrazov. Tako ternarnega operaterja ni mogoče preobremeniti.

Pomembne točke o preobremenitvi operaterja

1) Da preobremenitev operaterja deluje, mora biti vsaj eden od operandov uporabniško definiran objekt razreda.

2) Operator dodelitve: Prevajalnik samodejno ustvari privzeti operator dodelitve z vsakim razredom. Privzeti operater dodelitve dodeli vse člane desne strani levi strani in v večini primerov dobro deluje (to vedenje je enako kot konstruktor kopiranja). Glejte to za več podrobnosti.

3) Operater pretvorbe: Napišemo lahko tudi operatorje pretvorbe, ki jih lahko uporabimo za pretvorbo ene vrste v drugo.

primer:

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

>

podniz niza
>

Izhod

0.4>

Preobremenjeni operatorji pretvorbe morajo biti metoda člana. Drugi operaterji so lahko metoda člana ali globalna metoda.

4) Vsak konstruktor, ki ga je mogoče poklicati z enim samim argumentom, deluje kot pretvorbeni konstruktor, kar pomeni, da se lahko uporablja tudi za implicitno pretvorbo v razred, ki se konstruira.

primer:

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

>

>

Izhod

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

Kviz o preobremenitvi operaterja