C ++ Const Объяснение использования - PullRequest
92 голосов
/ 08 апреля 2011
const int* const Method3(const int* const&) const;

Может кто-нибудь объяснить использование каждого из const?

Ответы [ 12 ]

100 голосов
/ 08 апреля 2011

Это легче понять, если переписать его как полностью эквивалентный

// v───v───v───v───v───v───v───v───v───v───v───v─┬┐
//                                               ││
//  v──#1    v─#2             v──#3    v─#4      #5
   int const * const Method3(int const * const&) const;

затем прочитайте его справа налево.

# 5 говорит, что полное объявление функции слева - const, что означает, что это обязательно функция-член, а не свободная функция.

# 4 говорит, что указатель слева - const (нельзя изменить, чтобы он указывал на другой адрес).

# 3 говорит, что int слева - const (нельзя изменить на другое значение).

# 2 говорит, что указатель слева - const.

# 1 говорит, что int слева - const.

Собрав все это вместе, вы можете прочитать это как const функцию-член с именем Method3, которая принимает ссылку на const указатель на int const (или const int, если вы предпочитаете) и возвращает указатель const на int const (const int).

(N.b. # 2 совершенно лишнее .)

73 голосов
/ 08 апреля 2011

Читать это: https://isocpp.org/wiki/faq/const-correctness

Финальный const означает, что функция Method3 не изменяет неизменяемые члены своего класса.

const int* const означает константууказатель на константу int: то есть указатель, который не может быть изменен, на int, который не может быть изменен: единственное различие между этим и const int& состоит в том, что оно может быть null

const int* const& означаетссылка на постоянный указатель на константу int.Обычно указатели не передаются по ссылке;const int* & имеет больше смысла, потому что это будет означать, что указатель может быть изменен во время вызова метода, что является единственной причиной, по которой я вижу, как передать указатель по ссылке, const int* const& для всех намерений и целей совпадает с const int* const за исключением того, что он, вероятно, менее эффективен, поскольку указатели представляют собой простые старые типы данных (POD), и они, как правило, должны передаваться по значению.

22 голосов
/ 08 апреля 2011

Прежде всего const T эквивалентно T const.

Следовательно,

const int* const эквивалентно int const * const.

При чтении выражений с большим количеством const токенов и указателей в них, всегда старайтесь читать их справа налево (после применения преобразования выше). Так что в этом случае возвращаемое значение является константным указателем на констант int. Сам указатель const не имеет смысла, поскольку возвращаемое значение не является lvalue, которое можно изменить. Однако указатель const гарантирует, что вызывающая сторона не может изменить int (или массив int s), возвращаемый Method3.

const int*const& становится int const*const&, поэтому это ссылка на указатель const на const int. Передавать константный указатель по ссылкам male также не имеет смысла - вы не можете изменять ссылочное значение, так как указатель равен const, а ссылки и указатели занимают одинаковое пространство, поэтому экономия пространства также отсутствует.

Последний const указывает, что метод не изменяет объект this. Указатель this в теле метода будет иметь (теоретическое) объявление T const * const this. Это означает, что объект const T* сможет вызывать T::Method3().

12 голосов
/ 08 апреля 2011

Простой способ запомнить правила const - подумать об этом так: const относится к предмету слева, если слева ничего нет.

Таким образом, в случае const int * const первый const не имеет ничего слева, поэтому он применяется к int, а второй имеет что-то слева, поэтому он применяется к указателю.

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

3 голосов
/ 08 апреля 2011

Мне нравится использовать «часы» или «спиральный» метод , где начиная с имени идентификатора (в данном случае Method3) вы читаете взад-вперед слева направо back-to-left и т. д. для декодирования соглашений об именах. Таким образом, const int* const Method3(const int* const&) const - это метод класса, который не изменяет никаких членов класса (некоторого неназванного класса) и принимает постоянную ссылку на указатель, который указывает на постоянную int и возвращает постоянный указатель на константу int.

Надеюсь, это поможет,

Jason

2 голосов
/ 30 ноября 2014

Простой способ запомнить const в C ++ - это когда вы видите некоторый код в форме, такой как:

XXX const;
const YYY;

XXX, YYY будет постоянным компонентом,
XXX const форма:

function ( def var ) const;    ------#1
* const;                       ------#2

const YYY форма:

const int;                     ------#3
const double;

Люди обычно используют эти типы.Когда вы видите "const&" где-то, не смущайтесь, const описывает что-то перед собой.поэтому ответ на этот вопрос сейчас очевиден.

const int* const Method3(const int* const&) const;
  |          |             |          |       |
  #3         #2            #3         #2      #1
2 голосов
/ 08 апреля 2011
const /* don't modify the int or array of ints' value(s) */
int* const /* as a retval, ignored. useless declaration */
Method3(const /* don't modify the int or array of ints' value(s) */
int* const /* don't modify the pointer's value, the address to which `pointer` points to. e.g. you cannot say `++pointer` */
&) const; /* this method does not modify the instance/object which implements the method */
1 голос
/ 16 февраля 2015

Хочу только отметить, что const int* const& действительно является постоянной ссылкой на const int*.Например:

int i = 0;
int j = 1;
int* p = &i;
int* q = &j;
const int* const& cpref = p;
cpref = q; //Error: assignment of read-only reference 'cpref'

Это также относится к int* const&, что означает: «Постоянная ссылка на int*».
Но const int*& - это непостоянная ссылка на const int*.
Надеюсь, это поможет.

1 голос
/ 08 апреля 2011

const # 1: указатель, возвращаемый Method3, ссылается на const int.

const # 2: значение указателя, возвращаемое самой функцией, является const.Это бесполезное const (хотя и грамматически допустимое), поскольку возвращаемое значение из функции не может быть l-значением.

const # 3: тип указателя, переданный ссылкой на функцию, указывает на const int.

const # 4: значение указателя, переданное ссылкой на функцию, само является указателем const.Объявление значения, которое передается функции как const, обычно не имеет смысла, но это значение передается по ссылке, поэтому оно может быть значимым.

const # 5: функция (предположительно функция-член) является constЭто означает, что нельзя (а) присваивать новые значения любым членам объекта, частью которого он является, или (б) вызывать неконстантную функцию-член для объекта или любого из его членов.

1 голос
/ 08 апреля 2011

Чтение справа налево облегчает понимание модификаторов.

Метод const, который получает ссылку на константный указатель на const int с именем Method3, который возвращает константный указатель на const int.

  1. Метод const не может изменять элементы (если они не являются точными mutable)
  2. Указатель const нельзя изменить, чтобы он указывал на что-то еще
  3. Aconst int (или любой другой тип) не может быть изменен
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...