В чем разница между
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 указывает на класс, который можно изменить, в то время как вы не можете изменить параметр.
В первом вы объявляете функцию, которая принимает указатель на постоянный объект класса. Вы не можете изменить объект внутри функции. Во втором вы объявляете функцию, которая принимает постоянный указатель на неконстантный объект класса. Вы можете изменить объект с помощью указателя, но не можете изменить само значение указателя.
Я всегда помню это простое правило: const
всегда применяется к объекту, находящемуся непосредственно слева от него, если этот объект не существует, он применяется к объекту, находящемуся непосредственно справа.
Также взгляните на это вопрос, который я задал неделю назад, указывает на несколько очень полезных ссылок, чтобы понять правильность константы.
Эмпирическое правило состоит в том, чтобы читать объявления справа налево:
void func(const Class *myClass)
- это указатель на константный класс (или, строго говоря, "указатель на константный класс").
void func(Class *const myClass)
является постоянным указателем на класс
Хитрость заключается в том, чтобы прочитать эти вещи задом наперед:
void func(const Class *myClass)
Читает «myClass является указателем на класс, который является константой», что означает, что я не могу вносить изменения в класс
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
не может быть изменена так, чтобы она указывала на экземпляр класса. что-нибудь еще в теле функции.
Один важный момент, который не был поднят другими ответами, заключается в том, что для сигнатур функций любая константа верхнего уровня или изменчивая квалификация игнорируются при рассмотрении типа функции. Это связано с тем, что параметры всегда передаются по значению, поэтому то, являются ли они константами или нет, влияет только на то, может ли быть изменен сам параметр в теле функции, и не может повлиять на вызывающую программу.
Таким образом, эти два объявления функций эквивалентны.
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
указывать на какой-то другой объект.
Обратите внимание, что среди трех вышеперечисленных видов синтаксиса второй немного странный, но допустимый синтаксис. Это не следует правилу чтения слева направо, которое предлагают другие люди. Но тогда это жизнь на C++ для вас.