logo

Přetížení operátorů v C++

v C++ je přetížení operátorů polymorfismus v době kompilace. Jde o myšlenku dát zvláštní význam existujícímu operátoru v C++, aniž by se změnil jeho původní význam.

V tomto článku budeme dále diskutovat o přetěžování operátorů v C++ s příklady a uvidíme, které operátory můžeme nebo nemůžeme přetížit v C++.

Přetížení operátorů C++

C++ má schopnost poskytnout operátorům speciální význam pro datový typ, tato schopnost je známá jako přetížení operátorů. Přetížení operátorů je polymorfismus v době kompilace. Například můžeme přetížit operátor „+“ ve třídě, jako je String, takže můžeme zřetězit dva řetězce pouhým použitím +. Další příklady tříd, kde mohou být aritmetické operátory přetíženy, jsou komplexní čísla, zlomková čísla, velká celá čísla atd.



Příklad:

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

Zde jsou proměnné aab typu int a float, což jsou vestavěné datové typy. Proto operátor sčítání „+“ může snadno přidat obsah a a b. Je to proto, že operátor sčítání + je předdefinován pro přidávání proměnných pouze vestavěného datového typu.

Implementace:

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 příkladu máme 3 proměnné a1, a2 a a3 typu třídy A. Zde se pokoušíme přidat dva objekty a1 a a2, které jsou uživatelsky definovaného typu, tj. typu třídy A pomocí operátoru +. To není povoleno, protože operátor sčítání + je předdefinován tak, aby fungoval pouze s vestavěnými datovými typy. Ale zde je třída A uživatelem definovaný typ, takže kompilátor generuje chybu. Zde přichází na řadu koncept přetížení operátora.

Nyní, pokud chce uživatel přimět operátor + přidat dva objekty třídy, musí předefinovat význam operátoru + tak, aby přidal dva objekty třídy. To se provádí pomocí konceptu přetížení operátora. Takže hlavní myšlenkou přetěžování operátorů je použití operátorů C++ s proměnnými třídy nebo objekty třídy. Předefinování významu operátorů skutečně nemění jejich původní význam; místo toho jim byl dán další význam spolu s jejich stávajícími.

Příklad přetížení operátorů 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();> }>

síť a internet

>

>

Výstup

12 + i9>

Rozdíl mezi funkcemi operátora a normálními funkcemi

Funkce operátora jsou stejné jako normální funkce. Jediný rozdíl je v tom, že název funkce operátora je vždy klíčové slovo operátora následovaný symbolem operátoru a funkce operátora jsou volány při použití odpovídajícího operátoru.

Pří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;> }>

>

>

Výstup

12 + i9>

Můžeme přetížit všechny operátory?

Téměř všichni operátoři mohou být přetíženi kromě několika. Následuje seznam operátorů, které nelze přetížit.

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

Operátory, které lze v C++ přetížit

Můžeme přetížit

    Unární operátory Binární operátory Speciální operátory ( [ ], () atd.)

Ale mezi nimi jsou někteří operátoři, které nelze přetížit. Oni jsou

    Operátor rozlišení rozsahu (: Operátor výběru členů Výběr člena prostřednictvím *

Ukazatel na členskou proměnnou

    Podmíněný operátor (? Sizeof operator sizeof()
Operátoři, kteří mohou být přetíženi Příklady
Binární aritmetika +, -, *, /, %
Unární aritmetika +, -, ++, —
Úkol =, +=,*=, /=,-=, %=
bitový &, | , <> , ~ , ^
De-referencování (->)
Dynamická alokace paměti,
Zrušení přidělení
Nové, smazat
Dolní index [ ]
Volání funkce ()
Logický &, | |, !
Relační >, <, = =, =

Proč nemohou být výše uvedené operátory přetíženy?

1. velikost operátora

Vrátí velikost objektu nebo datového typu zadaného jako operand. To je vyhodnoceno kompilátorem a nelze jej vyhodnotit za běhu. Správné zvýšení ukazatele v poli objektů implicitně závisí na velikosti operátoru. Změna jeho významu pomocí přetížení by způsobila kolaps základní části jazyka.

2. typid operátor

To poskytuje programu CPP se schopností obnovit skutečně odvozený typ objektu, na který odkazuje ukazatel nebo odkaz. U tohoto operátora jde o to jednoznačně identifikovat typ. Pokud chceme, aby uživatelsky definovaný typ ‚vypadal‘ jako jiný typ, lze použít polymorfismus, ale význam operátoru typeid musí zůstat nezměněn, jinak by mohly nastat vážné problémy.

3. Rozlišení rozsahu (::) Operátor

To pomáhá identifikovat a specifikovat kontext, na který identifikátor odkazuje, zadáním jmenného prostoru. Je kompletně vyhodnocen za běhu a pracuje spíše s názvy než s hodnotami. Operandy rozlišení rozsahu jsou výrazy poznámek s datovými typy a CPP nemá žádnou syntaxi pro jejich zachycení v případě přetížení. Je tedy syntakticky nemožné tento operátor přetížit.

4. Operátoři přístupu členů třídy (.(tečka ), .* (ukazatel na členský operátor))

Důležitost a implicitní použití operátorů přístupu členů třídy lze pochopit z následujícího příkladu:

Příklad:

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>->skutečný = skutečný;> >this>->imaginární = imaginární;> >}> >void> print() { cout << real <<>' + i'> << imaginary; }> >ComplexNumber operator+(ComplexNumber c2)> >{> >ComplexNumber c3(0, 0);> >c3.real =>this>->real + c2.real;> >c3.imaginary =>this>->imaginární + c2.imaginární;> >return> c3;> >}> };> int> main()> {> >ComplexNumber c1(3, 5);> >ComplexNumber c2(2, 4);> >ComplexNumber c3 = c1 + c2;> >c3.print();> >return> 0;> }>

>

>

Výstup

5 + i9>

Vysvětlení:

Příkaz KomplexníČíslo c3 = c1 + c2; je interně přeloženo jako KomplexníČíslo c3 = c1.operátor+ (c2); za účelem vyvolání funkce operátora. Argument c1 je implicitně předán pomocí '.' operátor. Další příkaz také využívá operátor tečky pro přístup k členské funkci print a předání c3 jako argumentu.

Kromě toho tyto operátory také pracují se jmény a ne s hodnotami a neexistuje žádné ustanovení (syntakticky), které by je přetížilo.

5. Ternární nebo podmíněný (?:) Operátor

Ternární nebo podmíněný operátor je zkrácená reprezentace příkazu if-else. V operátoru jsou pravdivé/nepravdivé výrazy vyhodnoceny pouze na základě pravdivostní hodnoty podmíněného výrazu.

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

Funkce přetěžující ternární operátor pro třídu řekněme ABC pomocí definice

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

by nemohl zaručit, že byl vyhodnocen pouze jeden z výrazů. Ternární operátor tedy nemůže být přetížen.

Důležité body o přetížení operátora

1) Aby přetížení operátora fungovalo, musí být alespoň jeden z operandů uživatelem definovaný objekt třídy.

2) Operátor přidělení: Kompilátor automaticky vytvoří výchozí operátor přiřazení pro každou třídu. Výchozí operátor přiřazení přiřadí všechny členy pravé strany k levé straně a ve většině případů funguje dobře (toto chování je stejné jako u konstruktoru kopírování). Další podrobnosti naleznete zde.

3) Operátor konverze: Můžeme také napsat převodní operátory, které lze použít k převodu jednoho typu na jiný typ.

Příklad:

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

>

>

Výstup

příkaz java case
0.4>

Přetížené konverzní operátory musí být členskou metodou. Dalšími operátory mohou být buď členská metoda, nebo globální metoda.

4) Jakýkoli konstruktor, který lze volat pomocí jediného argumentu, funguje jako konstruktor převodu, což znamená, že jej lze použít také pro implicitní převod na konstruovanou třídu.

Pří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ýstup

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

Kvíz o přetížení operátora