Operație de atribuire în C++

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită pe 4 iunie 2017; verificările necesită 5 modificări .

Operatorul de atribuire în limbajul de programare C++ este notat prin semnul „=”. Ca și alți operatori din C++, acesta poate fi supraîncărcat cu .

Operația de atribuire de copiere este un tip special de operație de atribuire folosită pentru a atribui obiecte din aceeași clasă unul altuia. Este unul dintre membrii funcției speciale și este generat automat de compilator dacă nu există nicio declarație explicită din partea programatorului. Codul generat de compilator face o copie pe biți.

Operatorul de atribuire a copiei diferă de constructorul de copiere prin faptul că trebuie să curețe membrii de date ai țintei atribuirii (și să gestioneze în mod corespunzător autoatribuirea), în timp ce constructorul de copiere atribuie valori membrilor de date neinițializați. [1] De exemplu:

My_Array primul ; // inițializare cu constructorul implicit My_Array second = first ; // inițializare cu constructor de copiere secundă = primul ; // operație de atribuire prin copiere

Ca caz special, trebuie remarcată următoarea variantă de inițializare de către constructorul de copiere:

My_Array second = My_Array ();

În acest caz, compilatorul (de exemplu, VC2013) imediat, fără opțiuni de optimizare, efectuează optimizarea valorii returnate (RVO, optimizarea valorii returnate) și constructorul de copiere nu este apelat.

Supraîncărcarea sarcinii de copiere

Când vine vorba de a face copii profunde ale obiectelor, trebuie luată în considerare și gestionarea excepțiilor . O modalitate de a evita eroarea de mutare a resursei este următoarea:

  1. Obținerea de noi resurse
  2. Eliberarea resurselor vechi
  3. Atribuirea obiectului a valorilor noii resurse
clasa My_Array { int * matrice ; număr de int ; public : My_Array & operator = ( const My_Array & other ) { if ( this != & other ) // protecția împotriva autoatribuirii incorecte { // 1: alocați memorie „nouă” și copiați elemente int * new_array = new int [ other . numără ]; std :: copy ( other . array , other . array + other . count , new_array ); // 2: memoria „veche” liberă șterge [] matrice ; // 3: atribuiți valori în memoria „nouă” matricei de obiecte = new_array ; count = altul . numără ; } // prin convenție returnează întotdeauna *this return * this ; } ... };

Totuși, dacă o metodă de schimb de succes este disponibilă pentru toți membrii și clasa implementează un constructor de copiere și un destructor (conform regulii celor trei ), cea mai scurtă modalitate de a implementa o atribuire de copiere ar fi [2] :

public : void swap ( My_Array & other ) // schimbați funcția membru (nu ar trebui să eșueze!) { // schimbă toți membrii (și subobiectele subiacente dacă este posibil) cu alt std :: swap ( array , other . array ); std :: swap ( count , other . count ); } My_Array & operator = ( My_Array other ) // Notă: argumentul este transmis prin valoare! { // schimbă acest lucru cu alt schimb ( altul ); // prin convenție returnează întotdeauna *this return * this ; // altul este distrus, eliberând memoria }

Motivul pentru care operația =revine My_Array&în loc de voideste simplu. Este permisă combinarea sarcinilor, cum ar fi:

matrice_1 = matrice_2 = matrice_3 ; // valoarea matricei_3 este atribuită matricei_2 // apoi valoarea matricei_2 este atribuită matricei_1

Vezi și

Link -uri

  1. Bjarne Stroustrup . Limbajul de programare C++  (neopr.) . - 3. - Addison-Wesley , 2000. - S. 244. - ISBN 978-0201700732 .
  2. Sutter, H. & Alexandrescu, A. (octombrie 2004), C++ Coding Standards , Addison-Wesley , ISBN 0-321-11358-6