Указатели с ключевыми словами const и volatile
Константыи переменные ключевое слово изменяют способ обработки указателей. Ключевое слово const
указывает, что указатель не может быть изменен после инициализации; указатель будет защищен от изменения.
Ключевое слово volatile
указывает, что значение, связанное с именем, следующим образом, может быть изменено действиями, отличными от действий в пользовательском приложении. Таким образом, volatile
ключевое слово полезно для объявления объектов в общей памяти, к которым можно обращаться с помощью нескольких процессов или глобальных областей данных, используемых для взаимодействия с подпрограммами службы прерываний.
Когда имя объявляется как volatile
, компилятор перезагружает значение из памяти каждый раз, когда он обращается к программе. Это значительно сокращает возможности оптимизации. Однако если состояние объекта может неожиданно изменяться, то это единственный способ гарантировать предсказуемую производительность программы.
Чтобы объявить объект, на который указывает указатель, или const
volatile
используйте объявление формы:
const char *cpch;
volatile char *vpch;
Чтобы объявить значение указателя , то есть фактический адрес, хранящийся в указателе, как const
или volatile
используйте объявление формы:
char * const pchc;
char * volatile pchv;
Язык C++ запрещает назначения, позволяющие изменять объект или указатель, объявленный как const
. Такие присваивания могут удалить информацию, с которой был объявлен объект или указатель, и тем самым подменить смысл исходного объявления. Рассмотрим следующее объявление:
const char cch = 'A';
char ch = 'B';
Учитывая предыдущие объявления двух объектов (cch
типа const char и ch
типа char), допустимы следующие объявления и инициализации:
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;
Следующие объявления и инициализации вызывают ошибки.
char *pch2 = &cch; // Error
char *const pch3 = &cch; // Error
В объявлении pch2
задается указатель, при помощи которого может быть изменен постоянный объект, поэтому это объявление запрещено. Объявление pch3
указывает, что указатель является константой, а не объектом; объявление запрещено по той же причине pch2
, что объявление запрещено.
В следующих восьми примерах демонстрируется присваивание через указатель и изменение значения указателя для приведенных выше объявлений. Здесь мы предполагаем, что инициализация указателей pch1
–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
Указатели, объявленные как volatile
или как смесь const
и volatile
, подчиняются тем же правилам.
Указатели на const
объекты часто используются в объявлениях функций следующим образом:
errno_t strcpy_s( char *strDestination, size_t numberOfElements, const char *strSource );
Предыдущая инструкция объявляет функцию, strcpy_s, где два из трех аргументов имеют указатель char
типа. Так как аргументы передаются по ссылке, а не по значению, функция может быть свободна для изменения обоих strDestination
и strSource
, если strSource
они не были объявлены как const
. Объявление как const
гарантирует вызывающий strSource
объект, который strSource
не может быть изменен вызываемой функцией.
Примечание.
Так как существует стандартное преобразование из имени типа в имя* типа*const
, оно является законным для передачи аргумента типа char *
в strcpy_s. Однако обратное не верно; для удаления атрибута const
из объекта или указателя не существует неявного преобразования.
const
Указатель заданного типа можно назначить указателю того же типа. Однако указатель, который не const
может быть назначен указателю const
. В следующем коде показано одно верное и одно неверное присваивание.
// const_pointer.cpp
int *const cpObject = 0;
int *pObject;
int main() {
pObject = cpObject;
cpObject = pObject; // C3892
}
В следующем примере показано, как объявить объект как const, когда имеется указатель на указатель на объект.
// 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;
}
См. также
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по