Preopterećenje operatera u C + +: osnove, primjeri

U bilo kojoj znanosti postoje standardne oznake koje olakšavaju razumijevanje ideja. Na primjer, u matematici je množenje, podjela, dodavanje i druga simbolička oznaka. Izraz (x + y * z) mnogo je lakše razumjeti nego "pomnožiti y, c, z i dodati x". Zamislite, prije sedamnaestog stoljeća, matematika nije imala simboličke oznake, svi izrazi su pisani verbalno kao da je umjetnički tekst s opisom. I uobičajena oznaka za operacije pojavila se kasnije. Značenje kratkog zapisa o znakovima teško je precijeniti. Na temelju tih razmatranja, preopterećenja operatora dodani su programskim jezicima. Razmotrite primjer.

Primjer preopterećenja operatora

Gotovo kao i svaki drugi jezik, C ++ podržava mnoge operatore koji rade s tipovima podataka ugrađenim u jezični standard. No, većina programa koristi prilagođene tipove za rješavanje određenih zadataka. Na primjer, složena matematika ili matrična algebra realizirani su u programu zbog prikazivanja složenih brojeva ili matrica u obliku korisnički definiranih tipova C + +. Ugrađeni operatori ne znaju distribuirati svoj posao i obavljati potrebne postupke na korisničkim razredima, koliko god očito oni izgledaju. Stoga, za dodavanje matrica, na primjer, zasebna funkcija se obično stvara. Očito, poziv na sum_matrix (A, B) u kodu bit će manje jasan od izraza A + B.

Zastupanje složenog broja

Razmislite o približnoj klasi složenih brojeva:

// predstavljaju kompleksni broj u obliku para brojeva s plutajućom točkom. class complex {double re, im-public: kompleks (double r, double i): re (r), im (i) {} // constructorcomplex operator + - // prekomjerno opterećenje operatera additioncomplex * (kompleks) - // multiplication overload} -vraćeni glavni () {kompleks a {1, 2}, b {3, 4}, c {0, 0} -c = a + bc = a.operator + (b) - //// funkcija operatera može se nazvati kao bilo koja funkcija, zadani rekord je ekvivalentan kompleksu + bc = a * b + (1, 3) - // Uobičajena prioritetna pravila za dodavanje i umnožavanje su ispunjeni)

Slično tome, možete, na primjer, preopterećenja I / O operatora u C + + i prilagoditi ih da izlaze takve složene strukture kao matrice.

Operatori dostupni za preopterećenje

Potpuni popis svih operatora za koje možete koristiti mehanizam preopterećenja:

+

;

*

/

%

^

| |

~

!

=

<

+=

-=

* =

/ =

% =

^ =

=

| =

<<

> =

<<=

==

!=

<=

=

||

++



-;

-> *

,

->

[]

()

novi

novo []

izbrisati

izbriši []

Kao što možete vidjeti iz tablice, preopterećenje je prihvatljivo za većinu jezičnih operatora. Operator ne može biti preopterećen. To je učinjeno isključivo radi praktičnosti. Stoga operater preopterećenja u Javi, na primjer, nije dostupan. A sada o sljedećem važnom trenutku.

Operateri nisu preopterećeni

  • Rezolucija opsega je "::";
  • Izbor člana je ".";
  • Odabir člana putem pointera člana je ". *";
  • Ternarni uvjetni operater je "?:";
  • Operater sizeof;
  • Operater tipa.

Pravi operand tih operatera je ime, a ne vrijednost. Stoga bi rješavanje njihovog preopterećenja moglo dovesti do pisanja mnoštva dvosmislenih konstrukcija i uvelike bi otežalo život programera. Iako postoji mnogo programskih jezika u kojima se svi operatori mogu preopteretiti - na primjer, preopterećenje Python operatora.

ograničenja

Ograničenja operatora zbog preopterećenja:

Grafikon operatora dostupnih preopterećenju
  • Ne možete promijeniti binarni operator unarničkom operatoru i obratno, kao što ne možete dodati treći operand.
  • Ne možete izraditi nove operatore osim onih koji su dostupni. Ovo ograničenje uklanja mnoštvo nejasnoća. Ako postoji potreba za novim operatorom, u tu svrhu možete koristiti funkciju koja će obaviti potrebnu radnju.
  • Funkcija operatera može biti član klase ili imati barem jedan argument tipa koji je definiran od strane korisnika. Izuzeci su novi operatori i izbrišu. Ovo pravilo zabranjuje promjenu smisla izraza u slučaju da ne sadrže vrste objekata koje je odredio korisnik. Konkretno, ne možete stvoriti funkciju operatera koja radi isključivo s pokazivačima ili uzrokuje da operater dodavanja funkcionira kao množenje. Iznimka su operatori "=", "" i "," za klase objekata.
  • Funkcija operatera s prvim članom koji pripada jednoj od ugrađenih tipova podataka C ++ jezika ne može biti član klase.
  • Ime bilo koje funkcije operatera počinje s operatorom ključnih riječi, nakon čega slijedi simbolična oznaka samog operatora.
  • Ugrađeni operatori su definirani na takav način da postoji veza između njih. Na primjer, sljedeći operatori međusobno su jednaki: ++ x- x + = 1 x = x + 1. Nakon redefiniranja odnosa između njih neće se sačuvati. Očuvanje timskog rada na taj način s novim vrstama programera morat će se pobrinuti za odvojeno.
  • Prevodilac ne zna kako misliti. Izrazi z + 5 i 5 + z (gdje je z kompleksni broj) bit će drugačije obrađeni od strane prevodioca. Prvi je "složeni + broj", a drugi je "broj + kompleks". Stoga, za svaki izraz morate definirati vlastiti operator dodavanja.
  • Prilikom traženja definicije operatora, prevodilac ne daje prioritet funkcijama člana klase, niti pomoćnim funkcijama koje su definirane izvan razreda. Za prevodilac su jednake.

Tumačenje binarnih i neparnih operatora.

Binarni rad

Binarni operator je definiran kao funkcija člana s jednom varijablom ili kao funkcija s dvije varijable. Za svakog binarnog operatora @ sljedeće su konstrukcije valjane u izrazu a @ b, @:

operater @ (b) ili operator @ (a, b).

Razmotrite primjer klase složenih brojeva definicija operacija kao članova klase i pomoćnih.

klasni kompleks {double re, im-public: kompleks operator + = (kompleks z) -kompleks operater + (složeni z1, kompleks z2) -kompleksni operator + (kompleks z, dvostruki a) - kompleksni operater +

Koji će od operatora biti odabran, i hoće li biti odabran uopće, određuju interni mehanizmi jezika koji će se raspravljati u nastavku. Obično se to događa prema podudaranju tipa.

Izbor opisati funkciju kao član klase ili izvan njega - to je, u pravilu, okus. U gornjem primjeru, načelo selekcije bio je sljedeći: ako je operacija mijenja lijevi operand (na primjer, a + = b), a zatim ga snimiti u razredu i koristiti varijablu prijenos na, po svojoj neposrednoj Changes- ako operacija ne mijenja ništa i samo se vraća novu vrijednost ( npr + b) - nakon izdržati definicije klase.

Unarna i binarna operacija

Određivanje preopterećenja neparnih operatora u C + + vrši se na sličan način, s razlikom da su podijeljeni u dvije vrste:

  • operator prefiksa, koji se nalazi pred operandom, - @a, na primjer, ++ i. o je definiran kao a.operator @ () ili operator @ (aa);
  • operator postfixa koji se nalazi nakon operanda - b @, na primjer, i ++. o je definiran kao b.operator @ (int) ili operator @ (b, int)

Na isti način kao i kod binarnih operatera za slučaj kada je izjava operatora u klasi i izvan klase, izbor će biti izvršen pomoću mehanizama C + +.

Pravila o odabiru operatera

Vrste C ++ operatora

Neka se binarni operator @ primijeni na objekte x iz klase X i y iz klase Y. Pravila za rješavanje x ya bit će kako slijedi:

  1. ako je X klasa, pogledajte unutar nje za definiciju operatora @ kao člana X, ili osnovne klase X;
  2. pogledati kontekst u kojem se nalazi izraz x y;
  3. ako se X odnosi na prostor za imenik N, potražite deklaraciju operatora u N;
  4. ako se Y odnosi na prostor za imenik M, potražite izjavu operatera u M.

U slučaju da su nekoliko najava operatora operatora @ pronađene u 1-4, izbor će biti napravljen u skladu s pravilima za rješavanje preopterećenih funkcija.

Pretraga za neparničnim operatorima je upravo ista.

Pojašnjena definicija kompleksa

Sada ćemo detaljnije ilustrirati razred kompleksnih brojeva kako bismo pokazali niz prethodno izraženih pravila.

klasni kompleks {double re, im-public: kompleks operator + = (kompleks z) {// radi s izrazima oblika z1 + = z2re + = z.re-im + = z.im-povratak * ovaj-} kompleks operater + = (dvostruko) {// funkcionira s izrazima oblika z1 + = 5-re + = a-return * ovaj-} kompleks (): re (0), im (0) {} // konstruktor za inicijalizaciju po defaultu , Dakle, svi deklarirani kompleksni brojevi imaju početne vrijednosti (0, 0) kompleks (dvostruki r): re (r), im (0) {} // konstruktor omogućuje izraz kompleksnog oblika z = 11 - ekvivalent rekord z = kompleks (Kompleks z1, kompleks z2) {// funkcionira s izrazima oblika z1 + z2complex res = (kompleks z1, kompleks z2) z1-povratak res + = z2- // koristi operatera definiran kao funkcija člana} kompleksni operator + (kompleks z, dvostruki a) {// rukuje izraze oblika z + 2kompleks res = z- povratak res + = a-} kompleksni operator + (dvostruko, složeni z) {// procesira izraze oblika 7 + zcomplex res = z-povratak res + = a -} // hellip-

Kao što možete vidjeti iz koda, preopterećenje operatera ima vrlo složen mehanizam koji može narasti jako. Međutim, takav detaljan pristup dopušta preopterećenje čak i za vrlo složene podatkovne strukture. Na primjer, preopterećenje C + + izjava u predlošku klase.

Takvo stvaranje funkcija za sve i sve može biti dosadno i dovesti do pogrešaka. Na primjer, ako dodate treću vrstu u razmatrane funkcije, morat ćete razmotriti operacije iz razloga kombinacije tri vrste. Potrebno je napisati 3 funkcije jednim argumentom, 9 - s dva i 27 - s tri. Stoga, u brojnim slučajevima, implementacija svih tih funkcija i značajno smanjenje njihovog broja može se postići korištenjem pretvorbi tipa.

Posebni operatori

Operator indeksa "[]" mora uvijek biti definiran kao član klase, jer smanjuje ponašanje objekta u niz. Indeksiranje argument može biti bilo koje vrste, što omogućuje stvaranje, na primjer, asocijativnih polja.

Operater za pozivanje funkcije "()" može se smatrati binarnim postupkom. Na primjer, u konstrukciji izraz (popis izraza), lijevi operand binarnog operacija () je izraz, a desni operand je popis izraza. Funkcija operatora () () mora biti član klase.

Operator slijeda "," (zarez) poziva se na objekte ako postoji zarez pored njih. Međutim, operator ne sudjeluje u nabrajanju argumenata funkcije.

Operater dereferencija "->" također mora biti definiran kao član funkcije. U njenom značenju, može se definirati kao unary postfix operator. U tom slučaju mora nužno vratiti vezu ili pokazivač koji omogućuje pristup objektu.

Operator zadataka Također se određuje samo kao člana skupine zbog svoje povezanosti s lijeve operanda.

Operatori zadataka "=", adrese "" i sekvence "," moraju biti definirani u javnom bloku.

Rezultat

preopterećenje operatori pomažu implementirati jedan od ključnih aspekata OOP o polimorfizmu. No, važno je shvatiti da preopterećenje nije samo drukčiji način pozivanja funkcija. Zadatak preopterećenja operatora je često poboljšati razumijevanje koda, a ne osigurati dobitke u nekim pitanjima.

Što je polimorfizam?

I to nije sve. Također treba uzeti u obzir da je preopterećenje operatera složeni mehanizam s puno zamki. Stoga je vrlo lako napraviti pogrešku. To je glavni razlog zašto većina programera savjetuje da se suzdrže od preopterećenja operatera i da se pribjegne samo kao posljednjem mjestu i uz puno povjerenje u svoje postupke.

preporuke

C ++ Stvoritelj Bjarne Stroustrup
  1. Izvršite preopterećenje operatera samo za simuliranje poznatih zapisa. Kako bi kod postao čitljiviji. Ako kôd postaje složeniji u strukturi ili čitljivosti, trebali biste izbjeći preopterećenje operatera i upotrebljavati funkcije.
  2. Za velike operanada spasiti korištenje prostora proći argumente o vrsti stalne potrebe.
  3. Optimizirajte povratne vrijednosti.
  4. Nemojte dodirivati ​​rad kopiranja ako je prikladan za vaš razred.
  5. Ako kopiranje prema zadanim postavkama ne funkcionira, promijenite ili izričito zabranite kopiranje.
  6. Preporučujete funkcije članova preko funkcija koje nisu članice u slučajevima kada funkcije zahtijevaju pristup reprezentaciji klase.
  7. Navedite prostor imena i označite odnos funkcija s njihovom klasom.
  8. Koristite funkcije koje nisu članice za simetrične operatore.
  9. Koristite () operator za indekse u višedimenzionalnim poljem.
  10. Budite oprezni s implicitnim pretvorbama.
Dijelite na društvenim mrežama:

Povezan
Poljski poljski zapis: algoritam, metode i primjeriPoljski poljski zapis: algoritam, metode i primjeri
Odaberite tekst. Hrabar tip. HTML priručnik za početnikeOdaberite tekst. Hrabar tip. HTML priručnik za početnike
Što se može pripisati formalnim jezicima? Primjeri upotrebeŠto se može pripisati formalnim jezicima? Primjeri upotrebe
Popis glavnih HTML oznakaPopis glavnih HTML oznaka
BigInteger Java: radi s velikim brojemBigInteger Java: radi s velikim brojem
SQL INNER JOIN izjava: primjeri, sintaksa i značajkeSQL INNER JOIN izjava: primjeri, sintaksa i značajke
Timestamps u PHP-u: vremenske oznake i izračun vremenaTimestamps u PHP-u: vremenske oznake i izračun vremena
Što je HTML zaglavlje?Što je HTML zaglavlje?
Podučavamo dijete račun. Problemi i primjeri za prvu matematikuPodučavamo dijete račun. Problemi i primjeri za prvu matematiku
Popis predmeta u školi: znanje je temelj obrazovanjaPopis predmeta u školi: znanje je temelj obrazovanja
» » Preopterećenje operatera u C + +: osnove, primjeri
LiveInternet