logo

Sobrecàrrega de l'operador en C++

en C++, la sobrecàrrega de l'operador és un polimorfisme en temps de compilació. És una idea de donar un significat especial a un operador existent en C++ sense canviar el seu significat original.

En aquest article, parlarem més sobre la sobrecàrrega d'operadors en C++ amb exemples i veurem quins operadors podem o no sobrecarregar en C++.



Sobrecàrrega de l'operador C++

C++ té la capacitat de proporcionar als operadors un significat especial per a un tipus de dades, aquesta capacitat es coneix com a sobrecàrrega d'operadors. La sobrecàrrega de l'operador és un polimorfisme en temps de compilació. Per exemple, podem sobrecarregar un operador '+' en una classe com String perquè puguem concatenar dues cadenes amb només utilitzar +. Altres classes d'exemple on els operadors aritmètics es poden sobrecarregar són els nombres complexos, els nombres fraccionaris, els enters grans, etc.

Exemple:

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

Aquí, les variables a i b són de tipus int i float, que són tipus de dades integrats. Per tant, l'operador d'addició '+' pot afegir fàcilment el contingut de a i b. Això es deu al fet que l'operador d'addició + està predefinit per afegir variables només del tipus de dades integrat.



Implementació:

C++






data d'utilitat java

// C++ Program to Demonstrate the> // working/Logic behind Operator> // Overloading> class> A {> >statements;> };> int> main()> {> >A a1, a2, a3;> >a3 = a1 + a2;> >return> 0;> }>

>

>

En aquest exemple, tenim 3 variables a1, a2 i a3 de classe de tipus A. Aquí estem intentant afegir dos objectes a1 i a2, que són de tipus definit per l'usuari, és a dir, de classe de tipus A mitjançant l'operador +. Això no està permès, perquè l'operador d'addició + està predefinit per funcionar només amb tipus de dades integrats. Però aquí, la classe A és un tipus definit per l'usuari, de manera que el compilador genera un error. Aquí és on entra el concepte de sobrecàrrega de l'operador.

Ara, si l'usuari vol fer que l'operador + afegeixi dos objectes de classe, l'usuari ha de redefinir el significat de l'operador + de manera que afegeixi dos objectes de classe. Això es fa utilitzant el concepte de sobrecàrrega de l'operador. Per tant, la idea principal darrere de la sobrecàrrega d'operadors és utilitzar operadors C++ amb variables de classe o objectes de classe. Redefinir el significat dels operadors realment no canvia el seu significat original; en canvi, se'ls ha donat un significat addicional juntament amb els existents.

Exemple de sobrecàrrega d'operadors en 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();> }>

>

>

Sortida

12 + i9>

Diferència entre les funcions d'operador i les funcions normals

Les funcions de l'operador són les mateixes que les funcions normals. Les úniques diferències són que el nom d'una funció d'operador és sempre el paraula clau de l'operador seguit del símbol de l'operador, i les funcions d'operador es criden quan s'utilitza l'operador corresponent.

Exemple

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

>

>

Sortida

12 + i9>

Podem sobrecarregar tots els operadors?

Gairebé tots els operadors es poden sobrecarregar excepte alguns. A continuació es mostra la llista d'operadors que no es poden sobrecarregar.

com esborrar la columna a postgresql
sizeof typeid Scope resolution (::) Class member access operators (.(dot), .* (pointer to member operator)) Ternary or conditional (?:)>

Operadors que es poden sobrecarregar en C++

Podem sobrecarregar

    Operadors unaris Operadors binaris Operadors especials ( [ ], (), etc.)

Però, entre ells, hi ha alguns operadors que no es poden sobrecarregar. Ells són

    Operador de resolució d'abast (: operador de selecció de membres Selecció de membres mitjançant *

Punter a una variable membre

    Operador condicional (? Sizeof operador sizeof()
Operadors que es poden sobrecarregar Exemples
Aritmètica binària +, -, *, /, %
Aritmètica unària +, -, ++, —
Encàrrec =, +=,*=, /=,-=, %=
Bit a bit & , | , <> , ~ , ^
De-referencing (->)
Assignació de memòria dinàmica,
De-allocation
Nou, esborra
Subíndex [ ]
Crida de funció ()
Lògica &, | |, !
Relacional >, <, = =, =

Per què no es poden sobrecarregar els operadors anteriors?

1. grandària de l'operador

Això retorna la mida de l'objecte o tipus de dades introduït com a operand. Això és avaluat pel compilador i no es pot avaluar durant el temps d'execució. L'increment adequat d'un punter en una matriu d'objectes depèn implícitament de la mida de l'operador. Alterar el seu significat mitjançant la sobrecàrrega provocaria el col·lapse d'una part fonamental del llenguatge.

2. Typeid Operador

Això proporciona un programa CPP amb la capacitat de recuperar el tipus realment derivat de l'objecte al qual fa referència un punter o referència. Per a aquest operador, la qüestió és identificar de manera única un tipus. Si volem que un tipus definit per l'usuari 'sembli' un altre tipus, es pot utilitzar el polimorfisme però el significat de l'operador tipusid ha de romandre inalterat, o en cas contrari podrien sorgir problemes greus.

3. Resolució d'abast (::) Operador

Això ajuda a identificar i especificar el context al qual fa referència un identificador especificant un espai de noms. S'avalua completament en temps d'execució i funciona amb noms en lloc de valors. Els operands de resolució d'abast són expressions de notes amb tipus de dades i CPP no té una sintaxi per capturar-los si s'ha sobrecarregat. Per tant, és sintàcticament impossible sobrecarregar aquest operador.

4. Operadors d'accés als membres de la classe (.(punt ), .* (punter a l'operador membre))

La importància i l'ús implícit dels operadors d'accés de membres de classe es poden entendre a través de l'exemple següent:

Exemple:

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

>

>

Sortida

5 + i9>

Explicació:

La declaració ComplexNumber c3 = c1 + c2; es tradueix internament com ComplexNumber c3 = c1.operator+ (c2); per invocar la funció d'operador. L'argument c1 es passa implícitament utilitzant el ‘.’ operador. La següent instrucció també fa servir l'operador de punt per accedir a la funció membre print i passar c3 com a argument.

A més, aquests operadors també treballen en noms i no en valors i no hi ha cap disposició (sintàcticament) per sobrecarregar-los.

5. Operador ternari o condicional (?:).

L'operador ternari o condicional és una representació taquigràfica d'una declaració if-else. A l'operador, les expressions vertader/fals només s'avaluen en funció del valor de veritat de l'expressió condicional.

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

Una funció que sobrecarrega l'operador ternari d'una classe diu ABC utilitzant la definició

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

no podria garantir que només s'avalués una de les expressions. Així, l'operador ternari no es pot sobrecarregar.

Aspectes importants sobre la sobrecàrrega de l'operador

1) Perquè la sobrecàrrega d'operadors funcioni, almenys un dels operands ha de ser un objecte de classe definit per l'usuari.

2) Operador d'assignació: El compilador crea automàticament un operador d'assignació per defecte amb cada classe. L'operador d'assignació per defecte assigna tots els membres del costat dret al costat esquerre i funciona bé en la majoria dels casos (aquest comportament és el mateix que el constructor de còpia). Consulteu això per obtenir més detalls.

3) Operador de conversió: També podem escriure operadors de conversió que es poden utilitzar per convertir un tipus a un altre tipus.

Exemple:

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

>

>

Sortida

0.4>

Els operadors de conversió sobrecarregats han de ser un mètode membre. Altres operadors poden ser el mètode membre o el mètode global.

4) Qualsevol constructor que es pugui cridar amb un sol argument funciona com a constructor de conversió, el que significa que també es pot utilitzar per a la conversió implícita a la classe que s'està construint.

Exemple:

C++




cdr forma completa
// 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;> }>

>

>

Sortida

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

Test sobre la sobrecàrrega de l'operador