Suprasolicitare

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare

În programare , se numește supraîncărcare (sau supraîncărcare) crearea unei familii de funcții / subrutine care au toate același nume, dar acceptă un set diferit de argumente ( semnătură ) și, eventual, returnează o valoare de returnare diferită (în Java cu semnătura nu include valoarea returnată). Această familie de funcții este numită în relația de supraîncărcare sau supraîncărcată . Nu toate limbajele de programare permit supraîncărcarea.

În funcție de caz, putem vorbi despre supraîncărcarea funcțiilor, constructorilor și operatorilor . Supraîncărcarea constructorului unei clase este o practică obișnuită pentru dezvoltatorii de biblioteci , deoarece le permite să furnizeze dezvoltatorului final diferite modalități de instanțializare inițializând obiectul clasei cu anumite valori inițiale.

Supraîncărcarea constructorului și metodelor claselor

Iată câteva exemple de suprasolicitare a unui constructor „ Persoană ” și a unei metodeAddress Book.Insert ”, în limbajul Visual Basic (declarația unui tip enumerativ „Sex” de valoare „Masculin / Feminin” și a unor implementări este omisă)

 Persoană de clasă

Numele privat ca șir
Prenumele privat ca șir
Nașterea privată ca dată
Private _sex ca sex

Proprietatea publică ReadOnly FullName () Ca șir

Sub public Nou ( ByVal nume ca șir , ByVal prenume ca șir , ByVal naștere ca dată , ByVal sex ca sex )
    _nume = nume
    _surname = prenume
    _birth = naștere
    _sex = sex
end Sub

Sub Public Nou (ByVal AltraPersona Ca Persona)
    _nume = altă persoană . _Nume
    _surname = altă persoană . _nume
    _birth = altă persoană . _naștere
    _sex = altă persoană . _sex
end Sub
Clasa de sfârșit

Agenda telefonică a clasei
[ ... ]
Supraîncărcarea Public Sub Insert (ByVal Name Ca String, ByVal Nume ca șir)
Supraîncărcarea Public Sub Inserare (Articol ByVal Ca Persona)
Clasa de sfârșit

În acest fel este posibilă inițializarea unei instanțe a clasei Person fie prin furnizarea prenumelui și prenumelui ca șir, fie prin copierea acestora dintr-o altă instanță a Persoanei. Codul de mai sus este ușor de reutilizat în limbi precum C , C ++ , C # și Java , rescriind totul în conformitate cu sintaxa limbii alese.

Supraîncărcarea operatorului

Să luăm în considerare următorul exemplu C ++ : o clasă care reprezintă numere complexe (implementările fișierului .cpp sunt omise)

 clasa Complex
{
privat :
    _r dublu ;
    _i dublu ;

public :
    Complex ( int r , int i );
    Complex ( float r , float i );
    Complex ( dublu r , dublu i );
    Complex ( Complex c );
}

Am dori să putem efectua aceleași operații pe numerele complexe ca în mod normal pe numerele reale . De exemplu, am dori să putem rula următorul cod:

 Complexul c , d ;
...
dacă ( c < d )
    ....
...
cout << c ;

Acest cod ar genera o eroare de compilare , deoarece compilatorul nu poate evalua singur dacă complexul c este mai mic decât d și nici să-l scrie pe ecran. Soluția, care poate fi adoptată numai în C ++ și C # , este de a defini o suprasarcină adecvată pentru operatorii < și << . Pentru a face acest lucru, trebuie să știți cum tratează expresiile operatorului limbajul C. Le traduce printr-un apel către operatorul de subrutină ? () , Unde în loc de ? merge simbolul operatorului. Iată deci prototipurile (și câteva realizări) ale unei familii complete de supraîncărcare pentru operatorii principali de comparație și ieșire.

 // operator <
int operator < ( Complex a , Complex b )
{
    return (( a . r * a . r + a . i * a . i ) < ( b . r * b . r + b . i * b . i ));
}

int operator < ( Complex a , double b )
{
    return (( a . r * a . r + a . i * a . i ) < ( b * b ));
}

int operator < ( Complex a , float b );
int operator < ( Complex a , int b );
int operator < ( dublu a , Complex b );
int operator < ( float a , Complex b );
int operator < ( int a , Complex b );
 
// operator>
int operator > ( Complex a , Complex b )
{
   return (( a . r * a . r + a . i * a . i ) > ( b . r * b . r + b . i * b . i ));
}

int operator > ( Complex a , double b )
{
    return (( a . r * a . r + a . i * a . i ) > b * b );
}

int operator > ( Complex a , float b );
operator int > ( Complex a , int b );
int operator > ( dublu a , Complex b );
int operator > ( float a , Complex b );
int operator > ( int a , Complex b );

// operator <<
ostream & operator << ( ostream & out , Complex c )
{
    cout << c . r ;
    dacă ( c . i > 0 )
        cout << "+" ;
    cout << c . i << "i" ;
}

În limbajul Visual Basic este posibilă simularea supraîncărcării operatorului prin implementarea interfeței IComparable.

Note privind supraîncărcarea

O greșeală obișnuită a multor programatori este aceea de a dori să creeze două funcții care să ia aceleași tipuri de parametri de intrare și să returneze un tip diferit. Acest lucru nu este posibil, deoarece executantul identifică funcțiile și subrutinele , la nivel de asamblare , prin intermediul etichetelor (etichetă). Aceste etichete reflectă semnătura funcției în sine și, prin urmare, două etichete identice nu pot coexista în același spațiu de vizibilitate. Cu toate acestea, este posibil să definiți două sau mai multe funcții din aceeași semnătură în spații de nume diferite, fără a primi erori de compilare.

În cele din urmă, supraîncărcarea nu afectează executarea corectă a procedurilor recursive .

Elemente conexe