Assignment operators
Los operadores de asignación modifican el valor del objeto.
| Nombre del operador | Sintaxis | Sobrecargable | Ejemplos de prototipo (para class T ) | |
|---|---|---|---|---|
| Dentro de la definición de clase | Fuera de la definición de clase | |||
| asignación simple |
a = b
|
Sí | T & T :: operator = ( const T2 & b ) ; | N/A |
| asignación de adición |
a += b
|
Sí | T & T :: operator + = ( const T2 & b ) ; | T & operator + = ( T & a, const T2 & b ) ; |
| asignación de resta |
a -= b
|
Sí | T & T :: operator - = ( const T2 & b ) ; | T & operator - = ( T & a, const T2 & b ) ; |
| asignación de multiplicación |
a *= b
|
Sí | T & T :: operator * = ( const T2 & b ) ; | T & operator * = ( T & a, const T2 & b ) ; |
| asignación de división |
a /= b
|
Sí | T & T :: operator / = ( const T2 & b ) ; | T & operator / = ( T & a, const T2 & b ) ; |
| asignación de resto |
a %= b
|
Sí | T & T :: operator % = ( const T2 & b ) ; | T & operator % = ( T & a, const T2 & b ) ; |
| asignación AND bit a bit |
a &= b
|
Sí | T & T :: operator & = ( const T2 & b ) ; | T & operator & = ( T & a, const T2 & b ) ; |
| Asignación OR bit a bit |
a |= b
|
Sí | T & T :: operator | = ( const T2 & b ) ; | T & operator | = ( T & a, const T2 & b ) ; |
| asignación XOR bit a bit |
a ^= b
|
Sí | T & T :: operator ^ = ( const T2 & b ) ; | T & operator ^ = ( T & a, const T2 & b ) ; |
| asignación de desplazamiento a la izquierda bit a bit |
a <<= b
|
Sí | T & T :: operator <<= ( const T2 & b ) ; | T & operator <<= ( T & a, const T2 & b ) ; |
| asignación de desplazamiento a la derecha bit a bit |
a >>= b
|
Sí | T & T :: operator >>= ( const T2 & b ) ; | T & operator >>= ( T & a, const T2 & b ) ; |
|
||||
Contenidos |
Definiciones
Asignación de copia reemplaza los contenidos del objeto a con una copia de los contenidos de b ( b no se modifica). Para tipos de clase, esto se realiza en una función miembro especial, descrita en el operador de asignación de copia .
|
Asignación de movimiento reemplaza el contenido del objeto a con el contenido de b , evitando la copia si es posible ( b puede ser modificado). Para tipos de clase, esto se realiza en una función miembro especial, descrita en el operador de asignación de movimiento . |
(desde C++11) |
Para tipos no clase, la asignación por copia y la asignación por movimiento son indistinguibles y se denominan asignación directa .
Asignación compuesta reemplaza el contenido del objeto a con el resultado de una operación binaria entre el valor anterior de a y el valor de b .
Sintaxis del operador de asignación
Las expresiones de asignación tienen la forma
target-expr
=
new-value
|
(1) | ||||||||
| target-expr op new-value | (2) | ||||||||
| target-expr | - | la expresión [1] que será asignada |
| op | - | uno de * = , / = % = , + = - = , <<= , >>= , & = , ^ = , | = |
| new-value | - | la expresión [2] (hasta C++11) cláusula de inicialización (desde C++11) a asignar al objetivo |
- ↑ target-expr debe tener mayor precedencia que una expresión de asignación.
- ↑ new-value no puede ser una expresión de coma, porque su precedencia es menor.
|
Si new-value no es una expresión, la expresión de asignación nunca coincidirá con un operador de asignación compuesta sobrecargado. |
(since C++11) |
Operador de asignación simple incorporado
Para la asignación simple incorporada, target-expr debe ser un lvalue modificable.
El objeto referenciado por
target-expr
es modificado reemplazando su valor con el resultado de
new-value
. Si el objeto referenciado es de un tipo entero
T
, y el resultado de
new-value
es del tipo entero con signo/sin signo correspondiente, el valor del objeto es reemplazado con el valor de tipo
T
con la misma representación de valor del resultado de
new-value
.
El resultado de una asignación simple incorporada es un lvalue del tipo de target-expr , que hace referencia a target-expr . Si target-expr es un campo de bits , el resultado también es un campo de bits.
Asignación desde una expresión
Si new-value es una expresión, se convierte implícitamente al tipo sin calificadores cv de target-expr . Cuando target-expr es un campo de bits que no puede representar el valor de la expresión, el valor resultante del campo de bits está definido por la implementación.
Si target-expr y new-value identifican objetos que se superponen, el comportamiento es indefinido (a menos que la superposición sea exacta y el tipo sea el mismo).
|
Si el tipo de target-expr está calificado como volatile, la asignación está obsoleta, a menos que la expresión de asignación (posiblemente entre paréntesis) sea una expresión de valor descartado o un operando no evaluado . |
(since C++20) |
Asignación desde una cláusula inicializadora no expresiónnew-value solo se permite que no sea una expresión en las siguientes situaciones:
#include <complex> std::complex<double> z; z = {1, 2}; // meaning z.operator=({1, 2}) z += {1, 2}; // meaning z.operator+=({1, 2}) int a, b; a = b = {1}; // meaning a = b = 1; a = {1} = b; // syntax error |
(desde C++11) |
En
la resolución de sobrecarga frente a operadores definidos por el usuario
, para cada tipo
T
, las siguientes firmas de función participan en la resolución de sobrecarga:
|
T
*
&
operador
=
(
T
*
&
, T
*
)
;
|
||
|
T
*
volatile
&
operador
=
(
T
*
volatile
&
, T
*
)
;
|
||
Para cada tipo de enumeración o puntero a miembro
T
, opcionalmente calificado con volatile, la siguiente firma 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 como volatile) y
A2
es un tipo aritmético promovido, la siguiente firma de función participa en la resolución de sobrecarga:
|
A1
&
operator
=
(
A1
&
, A2
)
;
|
||
Operador de asignación compuesta incorporado
El comportamiento de cada expresión de asignación compuesta incorporada
target-expr
op
=
new-value
es exactamente igual al comportamiento de la expresión
target-expr
=
target-expr
op
new-value
, excepto que
target-expr
se evalúa solo una vez.
Los requisitos sobre target-expr y new-value de los operadores de asignación simples incorporados también se aplican. Además:
- Para + = y - = , el tipo de target-expr debe ser un tipo aritmético o un puntero a un tipo objeto completamente definido (posiblemente calificado cv).
- Para todos los demás operadores de asignación compuesta, el tipo de target-expr debe ser un tipo aritmético.
En
la resolución de sobrecarga frente a operadores definidos por el usuario
, para cada par
A1
y
A2
, donde
A1
es un tipo aritmético (opcionalmente calificado como volatile) y
A2
es un tipo aritmético promovido, las siguientes firmas de función participan en la resolución de sobrecarga:
|
A1
&
operador
*
=
(
A1
&
, A2
)
;
|
||
|
A1
&
operador
/
=
(
A1
&
, A2
)
;
|
||
|
A1
&
operador
+
=
(
A1
&
, A2
)
;
|
||
|
A1
&
operador
-
=
(
A1
&
, A2
)
;
|
||
Para cada par
I1
y
I2
, donde
I1
es un tipo integral (opcionalmente calificado como volatile) y
I2
es un tipo integral promovido, las siguientes firmas 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 calificado cv
T
, las siguientes firmas de función participan en la resolución de sobrecarga:
|
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
)
;
|
||
Ejemplo
#include <iostream> int main() { int n = 0; // no es una asignación n = 1; // asignación directa std::cout << n << ' '; n = {}; // inicialización a cero, luego asignación std::cout << n << ' '; n = 'a'; // promoción entera, luego asignación std::cout << n << ' '; n = {'b'}; // conversión explícita, luego asignación std::cout << n << ' '; n = 1.0; // conversión de punto flotante, luego asignación std::cout << n << ' '; // n = {1.0}; // error del compilador (conversión restrictiva) int& r = n; // no es una asignación r = 2; // asignación a través de referencia std::cout << n << ' '; int* p; p = &n; // asignación directa p = nullptr; // conversión a puntero nulo, luego asignación std::cout << p << ' '; struct { int a; std::string s; } obj; obj = {1, "abc"}; // asignación desde una lista de inicialización entre llaves std::cout << obj.a << ':' << obj.s << '\n'; }
Salida posible:
1 0 97 98 1 2 (nil) 1:abc
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Se aplica a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| CWG 1527 | C++11 |
para asignaciones a objetos de tipo clase, el operando derecho
solo podía ser una lista de inicialización cuando la asignación estaba definida por un operador de asignación definido por el usuario |
se eliminó la restricción de asignación
definida por el usuario |
| CWG 1538 | C++11 |
E1
=
{
E2
}
era equivalente a
E1
=
T
(
E2
)
(
T
es el tipo de
E1
), esto introducía un cast estilo C
|
es equivalente
a E1 = T { E2 } |
| CWG 2654 | C++20 |
los operadores de asignación compuesta para tipos
calificados con volatile se depreciaban de forma inconsistente |
ninguno de ellos
está depreciado |
| CWG 2768 | C++11 |
una asignación desde una cláusula inicializadora no-expresión
a un valor escalar realizaría inicialización de lista directa |
realiza inicialización de lista
por copia en su lugar |
| CWG 2901 | C++98 |
el valor asignado a un objeto
unsigned
int
a través de un lvalue int no estaba claro |
se aclaró |
| P2327R1 | C++20 |
los operadores de asignación compuesta bit a bit para tipos volatile
se depreciaban siendo útiles para algunas plataformas |
no están
depreciados |
Véase también
| Operadores comunes | ||||||
|---|---|---|---|---|---|---|
| asignación |
incremento
decremento |
aritméticos | lógicos | comparación |
acceso a
miembros |
otros |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
...
]
|
llamada a función
a ( ... ) |
|
coma
a, b |
||||||
|
condicional
a ? b : c |
||||||
| Operadores especiales | ||||||
|
static_cast
convierte un tipo a otro tipo relacionado
|
||||||
|
Documentación de C
para
Operadores de asignación
|