Разница между объявлениями const в C++

В чем разница между

void func(const Class *myClass)

а также

void func(Class *const myClass)

Смотрите также:

и наверное другие...


person user59688    schedule 28.01.2009    source источник


Ответы (6)


Разница в том, что для

void func(const Class *myClass)

Вы указываете на класс, который вы не можете изменить, потому что он константный. Но вы можете изменить указатель myClass (пусть он указывает на другой класс, это не имеет никаких побочных эффектов для вызывающего, потому что его указатель копируется, он только изменяет вашу локальную копию указателя) Напротив

void func(Class *const myClass)

Теперь myClass указывает на класс, который можно изменить, в то время как вы не можете изменить параметр.

person mmmmmmmm    schedule 28.01.2009

В первом вы объявляете функцию, которая принимает указатель на постоянный объект класса. Вы не можете изменить объект внутри функции. Во втором вы объявляете функцию, которая принимает постоянный указатель на неконстантный объект класса. Вы можете изменить объект с помощью указателя, но не можете изменить само значение указателя.

Я всегда помню это простое правило: const всегда применяется к объекту, находящемуся непосредственно слева от него, если этот объект не существует, он применяется к объекту, находящемуся непосредственно справа.

Также взгляните на это вопрос, который я задал неделю назад, указывает на несколько очень полезных ссылок, чтобы понять правильность константы.

person tunnuz    schedule 28.01.2009
comment
+1 за хороший ответ и совет о том, как запомнить константность, это то, что я тоже использую. - person xan; 28.01.2009

Эмпирическое правило состоит в том, чтобы читать объявления справа налево:

void func(const Class *myClass) - это указатель на константный класс (или, строго говоря, "указатель на константный класс").

void func(Class *const myClass) является постоянным указателем на класс

person jalf    schedule 28.01.2009
comment
для очень расплывчатых определений право->лево. Строго говоря, первое мне больше похоже на «указатель на класс const». - person Nate Parsons; 28.01.2009
comment
Это правило нарушается при виде этого: MyClass const *ptr - person Frederick The Fool; 28.01.2009
comment
drhorrible: класс, который тогда является константой, если вы хотите быть педантичным. ;) Фредерик: Почему? Указатель на константный MyClass? Кажется простым. - person jalf; 28.01.2009

Хитрость заключается в том, чтобы прочитать эти вещи задом наперед:

void func(const Class *myClass)

Читает «myClass является указателем на класс, который является константой», что означает, что я не могу вносить изменения в класс

void func(Class *const myClass)

Читает «myClass является константным указателем на класс», что означает, что я не могу изменить указатель.

person c0m4    schedule 28.01.2009

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);
person CB Bailey    schedule 28.01.2009

В С++ это

const MyClass *ptr 

и это

MyClass const *ptr

оба означают, что ptr является указателем переменной, указывающим на постоянный объект типа MyClass. То есть изменить указанный объект через ptr нельзя. Однако вы можете сделать так, чтобы ptr указывало на какой-то другой объект MyClass.

Напротив, это

MyClass *const ptr

подразумевает, что ptr является постоянным указателем, указывающим на объект переменной MyClass. Здесь вы действительно можете изменить объект, на который указывает ptr, но вы не можете заставить ptr указывать на какой-то другой объект.

Обратите внимание, что среди трех вышеперечисленных видов синтаксиса второй немного странный, но допустимый синтаксис. Это не следует правилу чтения слева направо, которое предлагают другие люди. Но тогда это жизнь на C++ для вас.

person Frederick The Fool    schedule 28.01.2009