Espacios de nombres
Variantes
Acciones

Operadores de asignación

De cppreference.com
< cpp‎ | language
 
 
 
Expresiones
General
categorías de valores (lvalue, rvalue, xvalue)
orden de evaluación (puntos de secuencia)
expresiones constantes
Operadores
Operadores de asignación: a=b, a+=b, a-=b, a*=b, a/=b, a%=b, a&=b, a|=b, a^=b, a<<=b, a>>=b
Operadores aritméticos: +a, -a, a+b, a-b, a*b, a/b, a%b, ~a, a&b, a|b, a^b, a<<b, a>>b
Incremento y decremento: ++a, --a, a++, a--
Operadores lógicos: a||b, a&&b, !a
Operadores de comparación: a==b, a!=b, a<b, a>b, a<=b, a>=b, a<=>b(C++20)
Operadores de acceso a miembro: a[b], *a, &a, a->b, a.b, a->*b, a.*b
Otros operadores: a(...), a,b, a?b:c
sizeof
alignof (C++11)
expresión new
expresión delete
typeid
 

Los operadores de asignación modifican el valor del objeto.

Nombre operador Sintaxis Sobrecargable Ejemplos de prototipos (para clase T)
Definición dentro de la clase Definición fuera de la clase
asignación simple a = b Si T& T::operator =(const T2& b); N/A
asiganación de movimiento (C++11) a = rvalue Si T& T::operator =(T2&& b); N/A
asignación suma a += b Si T& T::operator +=(const T2& b); T& operator +=(T& a, const T2& b);
asignación resta a -= b Si T& T::operator -=(const T2& b); T& operator -=(T& a, const T2& b);
asignación multiplicación a *= b Si T& T::operator *=(const T2& b); T& operator *=(T& a, const T2& b);
asignación división a /= b Si T& T::operator /=(const T2& b); T& operator /=(T& a, const T2& b);
asignación módulo de división a %= b Si T& T::operator %=(const T2& b); T& operator %=(T& a, const T2& b);
asignación AND sobre bits a &= b Si T& T::operator &=(const T2& b); T& operator &=(T& a, const T2& b);
asignación OR sobre bits a |= b Si T& T::operator |=(const T2& b); T& operator |=(T& a, const T2& b);
asignación XOR sobre bits a ^= b Si T& T::operator ^=(const T2& b); T& operator ^=(T& a, const T2& b);
asignación desplazamiento izquierda de bits a <<= b Si T& T::operator <<=(const T2& b); T& operator <<=(T& a, const T2& b);
asignación desplazamiento derecha de bits a >>= b Si T& T::operator >>=(const T2& b); T& operator >>=(T& a, const T2& b);
Notas
  • Todos los operadores de asignación integrados devuelven *this, y muchas de las sobrecargas definidas por el usuario también devuelven *this, por lo que los operadores definidos por el usuario se pueden usar de la misma forma que los integrados. Sin embargo, en una sobrecarga de operador definida por usuario, se puede usar cualquier tipo como tipo de retorno (incluyendo void).
  • T2 puede ser de cualquier tipo, incluyendo T.

Contenido

[editar] Explicación

El operador asignación copia modifica el contenido del objeto a por una copia del contenido de b (b no se modifica). Para los tipos clase, es una función miembro especial, descrita en operador de asignación copia.

El operador “asignación de movimiento” modifica el contenido del objeto a por el contenido de b, evitando copiar si es posible (b puede ser modificado). Para tipos clase, es una función miembro especial, descrita en operador asignación de movimiento. (desde C++11)

Para los tipos no clase, la asignación de copia y movimiento son indistinguibles y se denominan asignación directa.

Los operadores de asignación compuesta modifican el contenido del objeto a con el resultado de la operación binaria entre el valor anterior de a y el valor de b.

[editar] Asignación directa integrada

Las expresiones de asignación directa tienen la forma

lhs = rhs (1)
lhs = {} (2) (desde C++11)
lhs = {rhs} (3) (desde C++11)

Para el operador integrado, lhs tiene que tener un tipo no constante escalar y rhs debe ser implicitamente convertible al tipo de lhs.

El operador de asignación directa espera un lvalue modificable como su operando izquierdo y una expresión rvalue o una lista de inicio entre paréntesis (desde C++11) como su operando derecho, y retorna un lvalue identificando el operando izquierdo después de la modificación.

Para tipos no clase, el operando derecho primero se convierte implícitamente al tipo sin cualificar del operando izquierdo, y luego su valor se copia en el objeto identificado por el operando izquierdo.

Cuando el operando izquierdo tiene tipo referencia, el operador de asignación modifica el objeto referido.

Si los operandos izquierdo y derecho identifican objetos superpuestos, el comportamiento no está definido (a menos que el solapamiento sea exacto y el tipo sea el mismo)

Si el operando derecho es una lista de inicio entre paréntesis

  • si la expresión E1 tiene tipo escalar,
  • la expresión E1 = {} es equivalente a E1 = T{}, donde T es del tipo de E1.
  • la expresión E1 = {E2} es equivalente a E1 = T{E2}, donde T es del tipo de E1.
  • si la expresión E1 tiene un tipo clase, la sintaxis E1 = {args...} genera una llamada al operador de asignación con la lista de inicio entre paréntesis como el argumento, que luego selecciona el operador de asignación apropiado siguiendo las reglas de la resolución de sobrecarga. Tenga en cuenta que, si esta disponible un operador de asignación no de plantilla de algún tipo no clase, se prefiere a la asignación de copia/movimiento en E1 = {} porque {} a una no clase es una conversión de identidad, que prevalece sobre la conversión definida por el usuario para {} a un tipo clase.
(desde C++11)

En una resolución de sobrecarga para operadores definidos por usuario, para cada tipo T, el siguiente modelo de función participa en la resolución de sobrecarga:

T*& operator=(T*&, T*);
T*volatile & operator=(T*volatile &, T*);

Para cada enumeración o puntero a miembro de tipo T, opcionalmente calificado volátil, el siguiente modelo de función participa en la resolución de sobrecarga:

T& operator=(T&, T );

Para cada par A1 y A2, donde A1 es un tipo aritmético (opcionalmente calificado volátil) y A2 es un tipo promocionado a aritmético, el siguiente modelo de función participa en la resolución de sobrecarga:

A1& operator=(A1&, A2);

[editar] Ejemplo

#include <iostream>
int main()
{
    int n = 0;  // no es una asignación
    n = 1;      // asignación directa
    std::cout << n << ' ';
    n = {};     // inicialización cero, luego asignación
    std::cout << n << ' ';
    n = 'a';    // promoción a integral, luego asignación
    std::cout << n << ' ';
    n = {'b'};   // conversión explícita, luego asignación
    std::cout << n << ' ';
    n = 1.0;    // conversión de coma flotante, luego asignación
    std::cout << n << ' ';
//    n = {1.0}; // error de compilación  (narrowing conversion)
 
    int& r = n;  // no es una asignación
    int* p;
 
    r = 2;       // asignación a través de referencia
    std::cout << n << '\n';
    p = &n;      // asignación directa
    p = nullptr; // conversión de puntero nulo, luego asignación
 
    struct {int a; std::string s;} obj;
    obj = {1, "abc"}; // asignación con lista de inicio entre paréntesis
    std::cout << obj.a << ':' << obj.s << '\n';
}

Salida:

1 0 97 98 1 2
1:abc

[editar] Asignación compuesta integrada

Las expresiones de asignación compuesta tienen la forma

lhs op rhs (1)
lhs op {} (2) (desde C++11)
lhs op {rhs} (3) (desde C++11)
op - uno de *=, /= %=, += -=, <<=, >>=, &=, ^=, |=
lhs - para el operador integrado, lhs puede tener cualquier tipo aritmético, excepto cuando op es += o -=, que también acepta tipos puntero con las misma restricciones que + y -
rhs - para el operador integrado, rhs debe ser convertible implícitamente a lhs

El comportamiento de cada expresión de asignación compuesta integrada E1 op= E2 (donde E1 es una expresión lvalue modificable y E2 es una expresión rvalue o una lista de inicio entre paréntesis (desde C++11)) es exactamente el mismo que el de la expresión E1 = E1 op E2, excepto que la expresión E1 se evalúa solo una vez y se comporta como una sola operación con respecto a las llamadas de función sin secuencia determinada (por ejemplo, en f(a += b, g()), el += no se inicia o se completa como se ve desde dentro de g()).

En la resolución de sobrecarga para operadores definidos por usuario, para cada par A1 y A2, donde A1 es de tipo aritmético (opcionalmente calificado volátil) y A2 se promociona a tipo aritmético, los siguientes modelos de función participan en la resolución de sobrecarga:

A1& operator*=(A1&, A2);
A1& operator/=(A1&, A2);
A1& operator+=(A1&, A2);
A1& operator-=(A1&, A2);

Para cada par I1 y I2, donde I1 es de tipo entero (opcionalmente calificado volátil) y I2 es de tipo promocionado a entero, los siguientes modelos de función participan en la resolución de sobrecarga:

I1& operator%=(I1&, I2);
I1& operator<<=(I1&, I2);
I1& operator>>=(I1&, I2);
I1& operator&=(I1&, I2);
I1& operator^=(I1&, I2);
I1& operator|=(I1&, I2);

Para cada tipo de objeto opcionalmente cualificado constante-volátil T, los siguientes modelos de función participan en la resolución de sobre carga:

T*& operator+=(T*&, std::ptrdiff_t);
T*& operator-=(T*&, std::ptrdiff_t);
T*volatile & operator+=(T*volatile &, std::ptrdiff_t);
T*volatile & operator-=(T*volatile &, std::ptrdiff_t);


[editar] Ver también

Precedencia de operadores

Sobrecarga de operadores

Operadores comunes
asignación incremento/decremento aritmético lógico comparación acceso a miembro otros

a = b
a = rvalue
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

!a
a && b
a || b

a == b
a != b
a < b
a > b
a <= b
a >= b

a[b]
*a
&a
a->b
a.b
a->*b
a.*b

a(...)
a, b
(type) a
? :

Operadores especiales

static_cast convierte de un tipo a otro tipo compatible
dynamic_cast convierte de clase base virtual a clase derivada
const_cast convierte de un tipo a otro compatible con diferentes calificadores constante/volátil
reinterpret_cast convierte el tipo a tipo incompatible
new asigna memoria
delete desasigna memoria
sizeof consulta el tamaño de un tipo
sizeof... consulta el tamaño de un parámetro de paquete (desde C++11)
typeid consulta la información de un tipo
noexcept comprueba si una expresión puede lanzar una excepción (desde C++11)
alignof consultas requisitos de alineación de un tipo (desde C++11)

Documentacion C de Operadores de asignación