Разница между объявлениями const в C++
В чем разница между
void func(const Class *myClass)
а также
void func(Class *const myClass)
Смотрите также:
и, вероятно, другие...
6 ответов
Разница в том, что для
void func(const Class *myClass)
Вы указываете на класс, который вы не можете изменить, потому что он постоянный. Но вы можете изменить указатель myClass (пусть он указывает на другой класс; это не имеет побочных эффектов для вызывающей стороны, потому что указатель копируется, он только изменяет локальную копию указателя)
void func(Class *const myClass)
Теперь myClass указывает на класс, который можно изменить, пока вы не можете изменить параметр.
В первом вы объявляете функцию, которая принимает указатель на постоянный объект Class. Вы не можете изменить объект внутри функции. Во втором вы объявляете функцию, которая принимает постоянный указатель на неконстантный объект Class. Вы можете изменить объект через указатель, но не можете изменить само значение указателя.
Я всегда имею в виду это простое правило: const
всегда применяется к предмету, находящемуся непосредственно слева от него, если этот предмет не существует, он применяется к предмету, находящемуся непосредственно справа.
Также взгляните на этот вопрос, который я задавал неделю назад, он указывает на некоторые очень полезные ссылки, чтобы понять правильность const.
Основное правило - читать декларации справа налево:
void func(const Class *myClass)
указатель на const Class (или, строго говоря, "указатель на класс, который является const")
void func(Class *const myClass)
константный указатель на класс
void func(const Class *myClass) { //...
Как уже упоминалось в других ответах, это определение означает, что параметр myClass
указывает на случай Class
это не может быть изменено (mutable
а также const_cast
исключено) функцией. Тем не менее myClass
переменная в теле функции может быть изменена, чтобы указать на другой экземпляр Class
, Это деталь реализации функции.
void func(Class *const myClass) { // ...
С другой стороны, это определение означает, что myClass
параметр является указателем на Class
экземпляр, который не является константным и, следовательно, может использоваться функцией для полного управления экземпляром класса, но это myClass
Сама переменная-указатель не может быть изменена, чтобы указывать на что-либо еще в теле функции.
Один важный момент, который не был затронут другими ответами, заключается в том, что для сигнатур функций любой константный уровень или изменчивая квалификация игнорируется при рассмотрении типа функции. Это происходит потому, что параметры всегда передаются по значению, поэтому то, являются ли они постоянными или нет, влияет только на то, может ли сам параметр быть изменен в теле функции и не может повлиять на вызывающую функцию.
Таким образом, эти два объявления функций эквивалентны.
void func(Class *const myClass);
void func(Class *myClass);
Хитрость заключается в том, чтобы читать эти вещи задом наперед:
void func(const Class *myClass)
Читает "myClass - это указатель на класс, который является постоянным", что означает, что я не могу вносить изменения в класс
void func(Class *const myClass)
Читает "myClass является константным указателем на класс", что означает, что я не могу изменить указатель.
В С ++ это
const MyClass *ptr
и это
MyClass const *ptr
оба означают, что ptr
переменный указатель, который указывает на постоянный объект типа MyClass
, То есть вы не можете изменить указанный объект через ptr
, Тем не менее, вы можете сделать ptr
сам по себе указать какой-то другой объект MyClass
,
В отличие от этого
MyClass *const ptr
подразумевает ptr
постоянный указатель, указывающий на переменную MyClass
объект. Здесь вы действительно можете изменить объект, на который указывает ptr, но вы не можете сделать ptr
указать на какой-то другой объект.
Обратите внимание, что среди вышеупомянутых трех видов синтаксиса второй является немного странным, но это допустимый синтаксис. Это не следует правилу чтения слева направо, которое предлагают другие люди здесь. Но тогда это жизнь в C++ для вас.