cv (calificadores de tipo const y volatile)
Aparecen en cualquier especificador de tipo, incluyendo la sec-decl-especificadores de la gramática de declaraciones, para especificar la constantitud o la volatilidad de un objeto que está siendo declarado o del tipo que se le está dando nombre.
const
- Define que el tipo es constante.volatile
- Define que el tipo es volátil.
Contenido |
[editar] Explicación
Para cualquier tipo T
(incluyendo tipos incompletos), además de tipos función o tipos referencia, existen tres tipos distintos adicionales en el sistema de tipos de C++: calificado-const T
, calificado-volátil T
, y calificado-const-volátil T
.
- Nota: Los tipos array se consideran que tienen la misma calificación-cv que los tipos de sus elementos.
Cuando un objeto se crea por primera vez, los calificadores-cv utilizados (que podrían ser parte de una sec-decl-especificadores o parte de un declarador en una declaración, o parte de un id-de-tipo en una expresión-new) determinan la constantitud o la volatilidad de un objeto de la siguiente manera:
- objeto const - Un objeto cuyo tipo es calificado-const, o un subobjeto no-mutable de un objeto
const
. Tal objeto no puede ser modificado: intentar hacerlo directamente es un error en tiempo de compilación, e intentar hacerlo indirectamente (p. ej., modificando un objetoconst
mediante una referencia o un puntero a un tipo noconst
) resulta en comportamiento indefinido. - objeto volátil - Un objeto cuyo tipo está calificado-volátil, o un subobjeto de un objeto volátil, o un subobjeto mutable de un objeto const-volátil. Cada accesso (operación de lectura o de escritura, llamada a función miembro, etc.) hecho a través de una expresión glvalue de un tipo calificado-volátil se trata como un efecto secundario visible para los propósitos de optimización (es decir, dentro de un solo hilo de ejecución, los accesos volátiles no pueden ser optimizados o reordenados con otro efecto secundario visible que es secuenciado-antes o secuenciado-después del acceso volátil. Esto hace a los objetos volátiles adecuados para la comunicación con un controlador de señales, pero no con otro hilo de ejecución. Véase std::memory_order). Cualquier intento de referirse a un objeto volátil a través de un glvalue no volátil (p. ej., mediante una referencia o un puntero a un tipo no volátil) resulta en comportamiento indefinido.
- objeto const volátil - Un objeto cuyo tipo está calificado-const-volátil, un subobjeto no mutable de un objeto
const
volátil, un subobjetoconst
de un objeto volátil, o un subobjeto no mutable de un objetoconst
. Se comporta tanto como un objetoconst
como un objeto volátil.
Esta sección está incompleta Razón: discutir más sobre las diferencias entre objetos calificados-cv y expresiones calificadas-cv |
[editar] Especificador mutable
mutable
- Permite la modificación de un dato miembro declarado como mutable aún si el objeto que lo contiene se declara comoconst
.
Puede aparecer en la declaración de un dato miembro no estático de tipo referencia no const
:
class X { mutable const int* p; // de acuerdo mutable int* const q; // mal formado };
El especificador mutable
se utiliza para especificar que un dato miembro no afecta el estado externamente visible de la clase (y frecuentemente se usa para mutexes, cachés de memoria, evaluación perezosa e instrumentación de acceso).
class ContadorSeguroParaHilos { mutable std::mutex m; // La "regla M&M": mutable y mutex van juntos int datos = 0; public: int get() const { std::lock_guard<std::mutex> lk(m); return datos; } void inc() { std::lock_guard<std::mutex> lk(m); ++ datos; } };
[editar] Conversiones
Existe un orden parcial de calificadores-cv por el orden de restricciones incrementales. Puede decirse que el tipo es más o menos calificado-cv que:
- no-calificado <
const
- no-calificado <
volatile
- no-calificado <
const volatile
-
const
<const volatile
-
volatile
<const volatile
- no-calificado <
Las referencias y punteros a tipos calificados-cv pueden ser convertidos implícitamente a referencias y punteros a tipos más calificados-cv. En particular, las siguientes conversiones se permiten:
- referencia/puntero a un tipo no-calificado puede convertirse a una referencia/puntero a
const
- referencia/puntero a un tipo no-calificado puede convertirse a una referencia/puntero a
volatile
- referencia/puntero a un tipo no-calificado puede convertirse a una referencia/puntero a
const volatile
- referencia/puntero a un tipo
const
puede convertirse a una referencia/puntero aconst volatile
- referencia/puntero a un tipo
volatile
puede convertirse a una referencia/puntero aconst volatile
- referencia/puntero a un tipo no-calificado puede convertirse a una referencia/puntero a
- Nota: Se imponen restricciones adicionales en punteros de niveles múltiples.
Para convertir una referencia o un puntero a un tipo calificado-cv a una referencia, o un puntero a un tipo menos calificado-cv, se tiene que usar const_cast.
[editar] Palabras clave
[editar] Notas
El calificador const
usado en una declaración de una variable no local, no volátil, no-plantilla (desde C++14), no-inline (desde C++17) que no está declarada como extern
le da enlace interno. Esto es diferente de C, donde las variables en ámbito de archivo tienen enlace externo.
La gramática del lenguage C++ trata a mutable
como un especificador de clase de almacenamiento, en lugar de un calificador de tipo, pero no afecta la clase de almacenamiento o el enlace.
[editar] Ejemplo
int main() { int n1 = 0; // objeto no-const const int n2 = 0; // objeto const int const n3 = 0; // objeto const (lo mismo que n2) volatile int n4 = 0; // objeto volátil const struct { int n1; mutable int n2; } x = {0, 0}; // objeto const con miembro mutable n1 = 1; // de acuerdo, objeto modificable // n2 = 2; // ERROR: objeto no modificable n4 = 3; // de acuerdo, se trata como un efecto secundario // x.n1 = 4; // ERROR: miembro de un objeto const es const x.n2 = 4; // de acuerdo, miembro mutable de un objeto const no es const const int& r1 = n1; // referencia a const vinculada a objeto no-const // r1 = 2; // ERROR: intento de modificar mediante referencia a const const_cast<int&>(r1) = 2; // de acuerdo, modifica objeto no-const n1 const int& r2 = n2; // referencia a const vinculada a objeto const // r2 = 2; // ERROR: intento de modificar mediante referencia a const // const_cast<int&>(r2) = 2; // comportamiento indefinido: intento de modificar objeto const n2 }
Salida:
# código de máquina típico producido en una plataforma x86_64 # (solamente el código que contribuye a los efectos secundarios se emite) main: movl $0, -4(%rsp) # volatile int n4 = 0; movl $3, -4(%rsp) # n4 = 3; xorl %eax, %eax # return 0 (implícito) ret
[editar] Véase también
Documentación de C para calificador const
| |
Documentación de C para calificador volatile
|