Описание ключевого слова "const" на С++
При чтении руководств и кода, написанных на С++, я часто натыкаюсь на ключевое слово const
.
Я вижу, что он используется следующим образом:
const int x = 5;
Я знаю, что это означает, что x
является постоянной переменной и, вероятно, хранится в постоянной памяти.
Но что такое
void myfunc( const char x );
и
int myfunc( ) const;
?
Ответы
Ответ 1
void myfunc(const char x);
Это означает, что параметр x
является char, значение которого не может быть изменено внутри функции. Например:
void myfunc(const char x)
{
char y = x; // OK
x = y; // failure - x is `const`
}
Для последнего:
int myfunc() const;
Это незаконно, если только внутри функции объявления класса - const
не допускается модификация любого члена класса - не могут быть задействованы функции const
nonmember. в этом случае определение будет примерно таким:
int myclass::myfunc() const
{
// do stuff that leaves members unchanged
}
Если у вас есть определенные члены класса, которые должны быть модифицируемы в const
функциях-членах, вы можете объявить их mutable
. Примером может быть член lock_guard
, который делает функции-члены класса const
и не const
потокобезопасными, но должен меняться во время собственной внутренней операции.
Ответ 2
Первый пример функции более или менее бессмыслен. Более интересным будет:
void myfunc( const char *x );
Это сообщает компилятору, что содержимое *x
не будет изменено. То есть, внутри myfunc()
вы не можете сделать что-то вроде:
strcpy(x, "foo");
Второй пример, в функции члена С++, означает, что содержимое объекта не будет изменено вызовом.
Итак, дано:
class {
int x;
void myfunc() const;
}
someobj.myfunc()
не разрешается изменять что-либо вроде:
x = 3;
Ответ 3
Это:
void myfunc( const char x );
означает, что вы не можете изменить x
внутри функции, то есть это незаконно:
void myfunc( const char x ) {
x = ...;
}
а
int myfunc() const;
имеет смысл только в том случае, если myfunc() - метод внутри класса; это в основном означает, что метод не может модифицировать экземпляр класса (то есть состояние экземпляра до и после вызова instance.myfunc() будет одинаковым).
Ответ 4
Перед идентификатором переменной const
указывает, что переменная может быть инициализирована и после этого не изменена.
После имени метода класса const
указывает, что метод не будет изменять наблюдаемое состояние класса. Ключевое слово mutable
позволяет изменять внутренние данные.
Перед указателем или ссылочной переменной const
указывает, что идентификатор не будет использоваться для изменения ссылочных данных, хотя он может быть изменен другими способами.
const int *pInt = &x;
Const также может использоваться для указания того, что сам указатель не может быть изменен:
int * const pInt = &x;
Ответ 5
Я нашел очень хорошее объяснение: http://duramecho.com/ComputerInformation/WhyHowCppConst.html
В основном вся путаница заключается в разных вариантах использования для ключевого слова const
. В зависимости от того, где вы размещаете const
, вы говорите, что что-то должно быть неизменным или что-то не должно ничего менять. "что-то" может быть переменной или указателем или функцией/методом, которые вы не хотите, чтобы он мог изменять значение переменных, переданных функциям или переменным-членам объекта.
Ответ 6
Разница между двумя заключается в том, что первый имеет тип void(char)
, а второй имеет тип int()const
.
Функция, которая имеет такой тип с const
в конце, может быть только функцией-членом класса, а это означает, что функция-член не изменяет значение класса (к которому относится this
), как видно из-за пределов класса. Компилятор проверяет это до некоторой степени, и любая прямая запись члену класса в функцию-член-член приводит к ошибке времени компиляции, и функция может прямо вызывать только функции-члены-член-члены (специальные директивы существуют, поэтому вы можете указать что запись элемента не изменит значение класса, как видно извне. Это выполняется с помощью ключевого слова mutable
).
В представленных вами функциях задан параметр типа char const
. Такой параметр не может быть изменен внутри его функции. Однако это не влияет на тип функции и не влияет на вызывающих функции.
Ответ 7
void myfunc(const char x)
очень похож на const int x = 5
в вашем примере: он объявляет константу, локально доступную внутри функции myfunc
. Поскольку это константа, ее значение не может быть изменено.
int myfunc() const
является функцией-членом класса. const
указывает, что функция не изменит экземпляр класса, в котором выполняется функция. Таким образом, внутри функции вы не можете сделать что-то вроде this->foo = 7
или вызвать другую функцию, которая не является константой.
Ответ 8
Квалификатор const
означает, что переменная/указатель, определяемая как const
, не может быть изменена вашей программой, и она получит ее значение либо из явной инициализации, либо с помощью аппаратно-зависимого средства.
Указатель, который определяется как const
в объявлениях параметров, код функции не будет изменять то, на что указывает. В принципе, вы можете использовать указатель, и он в значительной степени функционирует как "только для чтения".
Например: -
void foo(const char *x)
{
while(*x)
{
if(*x==' ') cout << '-'; //printing - when a space is encountered
else cout << *x;
x++;
}
}
Вышеуказанная функция прекрасна и не будет отображаться никаких ошибок. Но если у foo была какая-то вещь, которая могла бы изменить переданную строку. скажем, функцию, которая заменяет пробелы на $. Не печатать $, а менять его на $. Что-то вроде этого: -
void foo(const char *x)
{
while(*x)
{
if(*x==' ') *x = '$'; //printing - when a space is encountered
else cout << *x;
x++;
}
}
то он не будет компилировать, то есть ошибку присваивания в ячейку памяти только для чтения.