logo

Operatörsöverbelastning i C++

i C++ är operatörsöverbelastning en kompileringstidspolymorfism. Det är en idé att ge speciell betydelse till en befintlig operator i C++ utan att ändra dess ursprungliga betydelse.

I den här artikeln kommer vi vidare att diskutera om operatörsöverbelastning i C++ med exempel och se vilka operatörer vi kan eller inte kan överbelasta i C++.



C++ Operatör överbelastning

C++ har förmågan att ge operatörerna en speciell betydelse för en datatyp, denna förmåga är känd som operatörsöverbelastning. Operatörsöverbelastning är en kompileringstidspolymorfism. Till exempel kan vi överbelasta en operator '+' i en klass som String så att vi kan sammanfoga två strängar genom att bara använda +. Andra exempelklasser där aritmetiska operatorer kan vara överbelastade är komplexa tal, bråktal, stora heltal, etc.

Exempel:

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

Här är variablerna a och b av typerna int och float, som är inbyggda datatyper. Därför kan additionsoperatorn '+' enkelt lägga till innehållet i a och b. Detta beror på att additionsoperatorn + är fördefinierad för att bara lägga till variabler av inbyggd datatyp.



Genomförande:

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

>

>

I det här exemplet har vi 3 variabler a1, a2 och a3 av typ klass A. Här försöker vi lägga till två objekt a1 och a2, som är av användardefinierad typ, dvs av typ klass A med +-operatorn. Detta är inte tillåtet eftersom additionsoperatorn + är fördefinierad att endast fungera på inbyggda datatyper. Men här är klass A en användardefinierad typ, så kompilatorn genererar ett fel. Det är här konceptet med operatörsöverbelastning kommer in.

Om användaren nu vill få operatorn + att lägga till två klassobjekt, måste användaren omdefiniera innebörden av + operatorn så att den lägger till två klassobjekt. Detta görs genom att använda konceptet Operatörsöverbelastning. Så huvudtanken bakom Operator-överbelastning är att använda C++-operatorer med klassvariabler eller klassobjekt. Att omdefiniera betydelsen av operatorer ändrar verkligen inte deras ursprungliga betydelse; istället har de fått ytterligare betydelse tillsammans med sina befintliga.

Exempel på operatörsöverbelastning i 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();> }>

>

>

anslutningar i java
Produktion

12 + i9>

Skillnad mellan operatörsfunktioner och normala funktioner

Operatörsfunktioner är desamma som normala funktioner. De enda skillnaderna är att namnet på en operatörsfunktion alltid är nyckelord för operatör följt av symbolen för operatören, och operatörsfunktioner anropas när motsvarande operatör används.

Exempel

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

>

>

Produktion

12 + i9>

Kan vi överbelasta alla operatörer?

Nästan alla operatörer kan överbelastas utom ett fåtal. Följande är listan över operatörer som inte kan överbelastas.

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

Operatörer som kan överbelastas i C++

Vi kan överbelasta

    Unära operatorer Binära operatorer Specialoperatorer ( [ ], () etc.)

Men bland dem finns det några operatörer som inte kan överbelastas. Dom är

    Operatör för upplösning av omfattning (: operatör för urval av medlemmar Medlemsval genom *

Pekare till en medlemsvariabel

    Villkorlig operator (? Sizeof operator sizeof()
Operatörer som kan överbelastas Exempel
Binär aritmetik +, -, *, /, %
Unär aritmetik +, -, ++, —
Uppdrag =, +=,*=, /=,-=, %=
Bitvis &, | , <> , ~ , ^
Avhänvisning (->)
Dynamisk minnesallokering,
Avfördelning
Nytt, radera
Index [ ]
Funktionsanrop ()
Logisk &, | |, !
Relationellt >, <, = =, =

Varför kan de ovan nämnda operatörerna inte överbelastas?

1. operatörens storlek

Detta returnerar storleken på objektet eller datatypen som angetts som operanden. Detta utvärderas av kompilatorn och kan inte utvärderas under körning. Den korrekta ökningen av en pekare i en array av objekt beror på operatorns storlek implicit. Att ändra dess innebörd med hjälp av överbelastning skulle få en grundläggande del av språket att kollapsa.

2. typid Operatör

Detta ger ett CPP-program med förmågan att återställa den faktiskt härledda typen av objektet som refereras till med en pekare eller referens. För den här operatören är hela poängen att unikt identifiera en typ. Om vi ​​vill få en användardefinierad typ att 'se ut' som en annan typ, kan polymorfism användas men innebörden av typid-operatorn måste förbli oförändrad, annars kan allvarliga problem uppstå.

3. Omfattningsupplösning (::) Operatör

Detta hjälper till att identifiera och specificera det sammanhang som en identifierare refererar till genom att ange ett namnområde. Det utvärderas helt under körning och fungerar på namn snarare än värden. Omfångsupplösningens operander är notuttryck med datatyper och CPP har ingen syntax för att fånga dem om den skulle vara överbelastad. Så det är syntaktisk omöjligt att överbelasta denna operatör.

4. Klassmedlemsåtkomstoperatörer (.(prick ), .* (pekare till medlemsoperatör))

Vikten och implicit användning av klassmedlemsåtkomstoperatörer kan förstås genom följande exempel:

Exempel:

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>->verklig = verklig;> >this>->imaginär = imaginär;> >}> >void> print() { cout << real <<>' + i'> << imaginary; }> >ComplexNumber operator+(ComplexNumber c2)> >{> >ComplexNumber c3(0, 0);> >c3.real =>this>->real + c2.real;> >c3.imaginary =>this>->imaginär + c2.imaginär;> >return> c3;> >}> };> int> main()> {> >ComplexNumber c1(3, 5);> >ComplexNumber c2(2, 4);> >ComplexNumber c3 = c1 + c2;> >c3.print();> >return> 0;> }>

>

>

Produktion

5 + i9>

Förklaring:

Satsen ComplexNumber c3 = c1 + c2; är internt översatt till ComplexNumber c3 = c1.operator+ (c2); för att anropa operatörsfunktionen. Argumentet c1 skickas implicit med hjälp av '.' operatör. Nästa sats använder också punktoperatorn för att komma åt medlemsfunktionen print och skicka c3 som ett argument.

Dessutom arbetar dessa operatörer också på namn och inte värden och det finns ingen bestämmelse (syntaktisk) för att överbelasta dem.

5. Ternär eller villkorlig (?:) Operatör

Den ternära eller villkorliga operatorn är en förkortad representation av en if-else-sats. I operatorn utvärderas sant/falskt uttryck endast på basis av sanningsvärdet för det villkorliga uttrycket.

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

En funktion som överbelastar den ternära operatorn för en klass, säg ABC med hjälp av definitionen

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

skulle inte kunna garantera att endast ett av uttrycken utvärderades. Således kan den ternära operatören inte överbelastas.

Viktiga punkter om operatörsöverbelastning

1) För att operatörens överbelastning ska fungera måste minst en av operanderna vara ett användardefinierat klassobjekt.

2) Uppdragsoperatör: Kompilatorn skapar automatiskt en standardtilldelningsoperator med varje klass. Standardtilldelningsoperatorn tilldelar alla medlemmar av höger sida till vänster sida och fungerar bra i de flesta fall (detta beteende är detsamma som kopieringskonstruktorn). Se detta för mer information.

3) Konverteringsoperatör: Vi kan också skriva konverteringsoperatorer som kan användas för att konvertera en typ till en annan typ.

Exempel:

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

>

>

Produktion

0.4>

Överbelastade konverteringsoperatorer måste vara en medlemsmetod. Andra operatörer kan antingen vara medlemsmetoden eller den globala metoden.

4) Vilken konstruktor som helst som kan anropas med ett enda argument fungerar som en konverteringskonstruktor, vilket innebär att den också kan användas för implicit konvertering till klassen som konstrueras.

Exempel:

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

>

insättningssorteringsalgoritm
>

Produktion

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

Frågesport om operatörsöverbelastning