Copiere și schimb

Idiomul copy-and-swap  este un limbaj de programare C++ care vă permite să proiectați declarații de atribuire tolerante .

Idioma se bazează pe expresia „ Obținerea unei resurse este inițializarea ”.

Idioma implică implementarea următoarelor funcții de membru al clasei:

Exemplu:

clasa Copiabil { public : Copiabil și operator = ( const Copiabil și _v ) { tmp copiabil ( _v ); this -> swap ( tmp ); returneaza * asta ; } void swap ( Copiabil & _v ) noexcept ; };

Toleranța la excepție înseamnă că Copyable& operator=(const Copyable &)nu există niciun punct într-o declarație de atribuire în care aruncarea unei excepții ar cauza o scurgere de memorie.

Operatorul de atribuire încearcă mai întâi să achiziționeze resursa „copie temporară a obiectului care se atribuie” ( tmp) și, dacă reușește, își schimbă conținutul cu conținutul obiectului curent ( this). Deoarece metoda este swapdeclarată ca nu aruncă excepții ( noexcept), singurul punct în care poate apărea o excepție este atunci când obiectul este copiat _v. Dacă copia eșuează, atunci controlul nu ajunge la metoda swap, altfel destructorul obiectului tmpeliberează resursele deținute anterior de obiectul curent ( this) (vezi expresia RAII ).

Implementarea de mai sus este, de asemenea, rezistentă la atribuirea obiectului însuși ( a=a), cu toate acestea, are suprasarcina asociată cu faptul că o copie temporară va fi creată și în acest caz. Puteți exclude costurile prin verificare suplimentară:

clasa Copiabil { public : Copiabil și operator = ( const Copiabil și _v ) { dacă ( acesta != & _v ) Copiabil ( _v ). swap ( * asta ); returneaza * asta ; } void swap ( Copiabil & _v ) noexcept ; };

Multe biblioteci standard C++ și containere și algoritmi STL presupun un operator de atribuire rezistent la excepții, dar fără a utiliza expresia de copiere și schimbare, uneori este destul de dificil să implementezi un astfel de operator de atribuire pentru clasele care conțin, de exemplu, pointeri către instanțe de alte clase.

Alte operațiuni

Având o funcție membru swapcare nu aruncă excepții, puteți utiliza o tehnică similară pentru a face orice operație pe un obiect garanție puternică pentru excepții .

Pentru a face acest lucru, faceți mai întâi o copie a obiectului existent, efectuați modificările necesare asupra copiei și apoi modificați *thisobiectul temporar.

  • dacă constructorul de copiere aruncă o excepție, atunci obiectul original nu este modificat și este îndeplinită garanția puternică de siguranță a excepției;
  • dacă se aruncă o excepție la schimbarea unui obiect temporar, atunci va fi chemat destructorul asupra obiectului temporar și se va îndeplini și garanția întrucât obiectul inițial nu a fost modificat;
  • dacă schimbarea la obiectul temporar a reușit, atunci se declanșează swap-ul și destructorul obiectului temporar, care nu aruncă excepții.

Vezi și

  • Idiom necopiabil