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-constT
, calificado-volátilT
, y calificado-const-volátilT
.
- 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 constint* 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 juntosint 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-constconstint n2 =0;// objeto constintconst n3 =0;// objeto const (lo mismo que n2)volatileint n4 =0;// objeto volátilconststruct{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 constint& r1 = n1;// referencia a const vinculada a objeto no-const// r1 = 2; // ERROR: intento de modificar mediante referencia a constconst_cast<int&>(r1)=2;// de acuerdo, modifica objeto no-const n1 constint& 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 |