const y volatile punteros
Las palabras clave de const y de volatile cambia cómo se tratan los punteros.La palabra clave de const especifica que el puntero no se puede modificar después de inicialización; el puntero se protege de modificación después.
La palabra clave de volatile especifica que el valor asociado con el nombre que sigue se puede modificar por acciones distintos de los de la aplicación.Por consiguiente, la palabra clave de volatile es útil para declarar objetos en memoria compartida que puedan obtener acceso varios procesos o áreas de datos globales utilizados para la comunicación con rutinas de servicio de interrupción.
Si un nombre se declara como volatile, las recargas de compilador el valor de memoria cada vez que se tiene acceso con el programa.Esto reduce considerablemente las optimizaciones posibles.Sin embargo, cuando el estado de un objeto puede cambiar inesperado, es la única forma garantizar el rendimiento del programa confiable.
Para declarar el objeto proporcionado por el puntero como const o volatile, utilice una declaración del formulario:
const char *cpch;
volatile char *vpch;
Para declarar el valor del puntero (es decir, la dirección real almacenada en el puntero (como const o volatile, utilice una declaración del formulario:
char * const pchc;
char * volatile pchv;
El lenguaje C++ evita las asignaciones que permitirían modificación de un objeto o un puntero declarado como const.Estas asignaciones quitarían información con la que el objeto o el puntero declararla, de esta manera infringiendo la intención de la declaración original.Considere las siguientes declaraciones:
const char cch = 'A';
char ch = 'B';
Dadas las declaraciones anteriores de dos objetos (cch, de const charcon tipo, y de ch, de **char)**escrita, la siguiente declaración o las inicializaciones es válido:
const char *pch1 = &cch;
const char *const pch4 = &cch;
const char *pch5 = &ch;
char *pch6 = &ch;
char *const pch7 = &ch;
const char *const pch8 = &ch;
La siguiente declaración o las inicializaciones es erróneas.
char *pch2 = &cch; // Error
char *const pch3 = &cch; // Error
La declaración de pch2 declara un puntero a través del cual un objeto constante podría ser modificado y por consiguiente se deniega.la declaración de pch3 especifica que pointer es constante, no el objeto; la declaración se deniega por la misma razón que se deniega la declaración de pch2 .
Las ocho asignaciones siguientes muestran la asignación con puntero y cambiar el valor del puntero para las declaraciones anteriores; por ahora, suponga que la inicialización era correcta para pch1 con pch8.
*pch1 = 'A'; // Error: object declared const
pch1 = &ch; // OK: pointer not declared const
*pch2 = 'A'; // OK: normal pointer
pch2 = &ch; // OK: normal pointer
*pch3 = 'A'; // OK: object not declared const
pch3 = &ch; // Error: pointer declared const
*pch4 = 'A'; // Error: object declared const
pch4 = &ch; // Error: pointer declared const
Los punteros declarados como volatile, o como una combinación de const y de volatile, siguen las mismas reglas.
Los punteros a objetos de const suelen utilizarse en declaraciones de función como sigue:
errno_t strcpy_s( char *strDestination, size_t numberOfElements, const char *strSource );
La instrucción anterior declara una función, strcpy_s, donde dos de los tres argumentos de tipo puntero a char.Dado que los argumentos se pasan por referencia y no por valor, la función quede libre de modificar strDestination y strSource si strSource no se declaró como const.La declaración de strSource como const garantiza que el llamador que strSource no se puede cambiar por la función llamada.
[!NOTA]
Dado que hay una conversión estándar typename *el typename *de const, se permite pasar un argumento de char * tipo a strcpy_s.Sin embargo, el inverso no es true; ninguna conversión implícita existe para quitar el atributo de const de un objeto o un puntero.
Un puntero de const de un tipo determinado se puede asignar a un puntero del mismo tipo.sin embargo, un puntero que no es const no se puede asignar a un puntero de const .El código siguiente se muestran las asignaciones correctas e incorrectas:
// const_pointer.cpp
int *const cpObject = 0;
int *pObject;
int main() {
pObject = cpObject;
cpObject = pObject; // C3892
}
El ejemplo siguiente se muestra cómo declarar un objeto como const si tiene un puntero a un puntero a un objeto.
// const_pointer2.cpp
struct X {
X(int i) : m_i(i) { }
int m_i;
};
int main() {
// correct
const X cx(10);
const X * pcx = &cx;
const X ** ppcx = &pcx;
// also correct
X const cx2(20);
X const * pcx2 = &cx2;
X const ** ppcx2 = &pcx2;
}