Разница между объявлениями const в C ++ - PullRequest
9 голосов
/ 28 января 2009

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

void func(const Class *myClass)

и

void func(Class *const myClass)

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

и, возможно, другие ...

Ответы [ 6 ]

21 голосов
/ 28 января 2009

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

void func(const Class *myClass)

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

void func(Class *const myClass)

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

11 голосов
/ 28 января 2009

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

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

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

5 голосов
/ 28 января 2009

Практическое правило - читать объявления справа налево:

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

void func(Class *const myClass) - это константный указатель на класс

2 голосов
/ 28 января 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);
2 голосов
/ 28 января 2009

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

void func(const Class *myClass)

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

void func(Class *const myClass)

Читает "myClass - это константный указатель на класс", что означает, что я не могу изменить указатель.

1 голос
/ 28 января 2009

В C ++ это

const MyClass *ptr 

и это

MyClass const *ptr

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

В отличие от этого

MyClass *const ptr

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

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

...