Copiar e intercambiar

El modismo de copiar e intercambiar  es un modismo del lenguaje de programación C++ que le permite diseñar sentencias de asignación tolerantes a excepciones .

El modismo se basa en el modismo " Obtener un recurso es inicializar ".

El modismo implica la implementación de las siguientes funciones miembro de clase:

Ejemplo:

clase copiable { público : Copiable y operador = ( const Copiable y _v ) { tmp copiable ( _v ); esto -> intercambiar ( tmp ); devolver * esto ; } void swap ( Copiable & _v ) noexcept ; };

La tolerancia a excepciones significa que Copyable& operator=(const Copyable &)no tiene sentido en una declaración de asignación en la que lanzar una excepción podría causar una pérdida de memoria.

El operador de asignación primero intenta adquirir el recurso de "copia temporal del objeto que se está asignando" ( tmp) y, si tiene éxito, cambia su contenido con el contenido del objeto actual ( this). Dado que el método se swapdeclara como que no lanza excepciones ( noexcept), el único punto donde puede ocurrir una excepción es cuando se copia el objeto _v. Si la copia falla, entonces el control no llega al método swap; de lo contrario, el destructor del objeto tmplibera los recursos que antes pertenecían al objeto actual ( this) (ver el modismo RAII ).

La implementación anterior también es resistente a las asignaciones del objeto a sí mismo ( a=a); sin embargo, tiene la sobrecarga asociada con el hecho de que también se creará una copia temporal en este caso. Puede excluir los costos mediante un cheque adicional:

clase copiable { público : Copiable y operador = ( const Copiable y _v ) { si ( esto != & _v ) Copiable ( _v ). intercambiar ( * esto ); devolver * esto ; } void swap ( Copiable & _v ) noexcept ; };

Muchos contenedores y algoritmos de C++ Standard Library y STL asumen un operador de asignación resistente a excepciones, pero sin usar el idioma de copiar e intercambiar, a veces es bastante difícil implementar dicho operador de asignación para clases que contienen, por ejemplo, punteros a instancias de otras clases.

Otras operaciones

Al tener una función miembro swapque no genera excepciones, puede usar una técnica similar para realizar cualquier operación en un objeto con una fuerte garantía de excepción segura .

Para hacer esto, primero haga una copia del objeto existente, realice las modificaciones necesarias en la copia y luego cambie *thisel objeto temporal.

  • si el constructor de la copia lanza una excepción, entonces el objeto original no se modifica y se cumple la fuerte garantía de seguridad de la excepción;
  • si se lanza una excepción cuando se cambia un objeto temporal, entonces se llamará al destructor sobre el objeto temporal y la garantía también se cumplirá ya que el objeto original no ha sido modificado;
  • si el cambio en el objeto temporal se realizó correctamente, se activan el intercambio y el destructor del objeto temporal, que no generan excepciones.

Véase también

  • Modismo no copiable