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