En el lenguaje de programación C++ , el operador de asignación , , es el operador utilizado para la asignación . Al igual que la mayoría de los demás operadores en C++, puede sobrecargarse .=
El operador de asignación por copia , a menudo llamado simplemente "operador de asignación", es un caso especial de operador de asignación donde el origen (lado derecho) y el destino (lado izquierdo) son del mismo tipo de clase . Es una de las funciones miembro especiales , lo que significa que el compilador genera automáticamente una versión predeterminada si el programador no declara ninguna. La versión predeterminada realiza una copia miembro por miembro, donde cada miembro se copia mediante su propio operador de asignación por copia (que también puede ser declarado por el programador o generado por el compilador).
El operador de asignación por copia se diferencia del constructor de copia en que debe limpiar los miembros de datos del destino de la asignación (y manejar correctamente la autoasignación), mientras que el constructor de copia asigna valores a miembros de datos no inicializados. [ 1 ] Por ejemplo:
MyArray first ; // inicialización por constructor predeterminado MyArray second ( first ); // inicialización por constructor de copia MyArray third = first ; // También inicialización por constructor de copia second = third ; // asignación por operador de asignación de copiaValor de retorno del operador de asignación sobrecargado
El lenguaje permite que un operador de asignación sobrecargado tenga un tipo de retorno arbitrario (incluido void). Sin embargo, el operador generalmente se define para devolver una referencia al objeto asignado. Esto es coherente con el comportamiento del operador de asignación para tipos integrados ( que devuelve el valor asignado ) y permite usar la invocación del operador como una expresión, por ejemplo, en sentencias de control o en asignaciones encadenadas . Además, la biblioteca estándar de C++ requiere este comportamiento para algunos tipos proporcionados por el usuario. [ 2 ]
Operador de asignación de copias de sobrecarga
Cuando se deben realizar copias profundas de objetos, se debe tener en cuenta la seguridad ante excepciones . Una forma de lograr esto cuando la desasignación de recursos nunca falla es:
- Adquirir nuevos recursos
- Liberar recursos antiguos
- Asigne los identificadores de los nuevos recursos al objeto.
clase MyArray { int * array ; int count ; public : MyArray & operator = ( const MyArray & other ) { if ( this != & other ) { // proteger contra autoasignación no válida // 1: asignar nueva memoria y copiar los elementos int * new_array = new int [ other . count ]; std :: copy ( other . array , other . array + other . count , new_array );// 2: liberar la memoria antigua eliminar [] array ;// 3: asigna la nueva memoria al objeto array = new_array ; count = other.count ; } // por convención, siempre devuelve *this return * this ; } // ... };Sin embargo, si existe una función de intercambio sin fallos ( sin lanzamientos ) disponible para todos los subobjetos miembros y la clase proporciona un constructor de copia y un destructor (lo que debería hacer según la regla de tres ), la forma más sencilla de implementar la asignación de copia es la siguiente: [ 3 ]
public : // la función miembro swap (¡nunca debería fallar!) void swap ( MyArray & other ) { // intercambia todos los miembros (y el subobjeto base, si corresponde) con other using std :: swap ; // debido a ADL el compilador usará // swap personalizado para los miembros si existe // recurriendo a std::swap swap ( array , other.array ) ; swap ( count , other.count ); }// nota: ¡argumento pasado por valor! MyArray & operator = ( MyArray other ) { // intercambiar esto con other swap ( other );// por convención, siempre devuelve *this return * this ;// el otro se destruye, liberando la memoria }Asignación entre diferentes clases
C++ admite la asignación entre diferentes clases, tanto a través del constructor de copia implícito como del operador de asignación, si la clase de instancia de destino es antecesora de la clase de instancia de origen:
clase Ancestro { público : int a ; };clase Descendiente : público Ancestro { público : int b ; };int main () { Descendiente d ; Ancestro a ( d ); Ancestro b ( d ); a = d ; }No está permitido copiar objetos de un ancestro a un descendiente, ya que esto podría dejar los campos del descendiente sin inicializar.
Véase también
Referencias
- ↑ Stroustrup, Bjarne (2000). El lenguaje de programación C++ (3.ª ed.). Addison-Wesley. pág. 244. ISBN 978-0-201-70073-2.
- ↑ Borrador de trabajo, Estándar para el lenguaje de programación C++, Sección 17.6.3.1, Tabla 23; http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
- ↑ Sutter, H. ; Alexandrescu, A. (octubre de 2004), Estándares de codificación de C++ , Addison-Wesley , ISBN 0-321-11358-6
Enlaces externos
- Anatomía del operador de asignación , por Richard Gillam
- C++
- Operadores (programación)
- Operaciones de asignación