Ponteiros const e volatile
As palavras-chave const e volatile mudam o tratamento dos ponteiros. A palavra-chave const
especifica que o ponteiro não pode ser alterado depois da inicialização; o ponteiro é protegido contra modificações posteriores.
A palavra-chave volatile
especifica que o valor associado ao nome que segue pode ser alterado por ações diferentes daquelas do aplicativo do usuário. Portanto, a palavra-chave volatile
é útil para declarar objetos na memória compartilhada que podem ser acessados por vários processos ou por áreas de dados globais usados na comunicação com rotinas de serviço de interrupção.
Quando um nome é declarado como volatile
, o compilador recarrega o valor da memória sempre que é acessado pelo programa. Isso reduz drasticamente as otimizações possíveis. No entanto, quando o estado de um objeto pode ser alterado inesperadamente, é a única maneira de assegurar o desempenho previsível do programa.
Para declarar o objeto apontado pelo ponteiro como const
ou volatile
, use uma declaração da forma:
const char *cpch;
volatile char *vpch;
Para declarar o valor do ponteiro, ou seja, o endereço real armazenado no ponteiro, como const
ou volatile
, use uma declaração da forma:
char * const pchc;
char * volatile pchv;
A linguagem C++ impede as atribuições que permitiriam a alteração de um objeto ou um ponteiro declarado como const
. Essas atribuições removeriam as informações com as quais o objeto ou o ponteiro foi declarado, violando assim a intenção da declaração original. Considere as seguintes declarações:
const char cch = 'A';
char ch = 'B';
Dadas as declarações anteriores de dois objetos (cch
, do const char, e ch
, do tipo char ), as seguintes declarações/inicializações serão válidas:
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;
As seguintes declarações/inicializações são errôneas.
char *pch2 = &cch; // Error
char *const pch3 = &cch; // Error
A declaração de pch2
declara um ponteiro em que um objeto constante pode ser modificado e, portanto, não é permitida. A declaração de pch3
especifica que é constante, não ao objeto; a declaração não é permitida pelo mesmo motivo que a declaração pch2
não é permitida.
As oito atribuições a seguir mostram a atribuição por ponteiro e a alteração do valor do ponteiro para as declarações anteriores; por enquanto, suponha que a inicialização estava correta para pch1
a 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
Os ponteiros declarados como volatile
, ou como uma mistura de const
e volatile
, obedecem às mesmas regras.
Os ponteiros para os objetos const
são usados frequentemente em declarações de função como segue:
errno_t strcpy_s( char *strDestination, size_t numberOfElements, const char *strSource );
A instrução anterior declara uma função, strcpy_s, onde dois dos três argumentos são do tipo ponteiro para char
. Como os argumentos são passados por referência e não por valor, a função é livre para alterar strDestination
e strSource
se strSource
não for declarado como const
. A declaração de strSource
como const
assegura que o strSource
não possa ser alterado pela função chamada.
Observação
Como há uma conversão padrão de typename* em const
typename*, pode passar um argumento de tipo char *
para strcpy_s. No entanto, o contrário não é válido; não há conversão implícita para remover o atributo const
de um objeto ou ponteiro.
Um ponteiro const
de determinado tipo pode ser atribuído a um ponteiro do mesmo tipo. No entanto, um ponteiro que não é const
não pode ser atribuído a um ponteiro const
. O código a seguir mostra atribuições corretas e incorretas:
// const_pointer.cpp
int *const cpObject = 0;
int *pObject;
int main() {
pObject = cpObject;
cpObject = pObject; // C3892
}
O exemplo a seguir mostra como declarar um objeto como const se você tiver um ponteiro para um ponteiro para um 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;
}
Confira também
Comentários
https://aka.ms/ContentUserFeedback.
Brevemente: Ao longo de 2024, vamos descontinuar progressivamente o GitHub Issues como mecanismo de feedback para conteúdos e substituí-lo por um novo sistema de feedback. Para obter mais informações, veja:Submeter e ver comentários