[C++] В чем разница между const int *, const int * const и int const *?


Answers

Для тех, кто не знает о правиле по часовой стрелке / спирали: начните с имени переменной, перемещайте по часовой стрелке (в данном случае, переместитесь назад) к следующему указателю или типу . Повторяйте до окончания выражения.

вот демо:

Question

Я всегда испортил, как правильно использовать const int* , const int * const и int const * . Существует ли набор правил, определяющих, что вы можете и чего не можете сделать?

Я хочу знать все дела, и все это не касается заданий, передачи функций и т. Д.




Как и многие, все отметили:

В чем разница между const X* p , X* const p и const X* const p ?

Вы должны прочитать декларации указателей справа налево.

  • const X* p означает «p указывает на X, который является const»: объект X не может быть изменен через p.

  • X* const p означает, что «p - это указатель на const, который не является const»: вы не можете изменить указатель p, но вы можете изменить объект X через p.

  • const X* const p означает, что «p - это указатель const на X, который является const»: вы не можете изменить указатель p самостоятельно, и вы не можете изменить объект X через p.




Общее правило заключается в том, что ключевое слово const применяется к тому, что предшествует ему немедленно. Исключение составляет начальная const .

  • const int* совпадает с int const* и означает «указатель на константу int» .
  • const int* const совпадает с int const* const и означает «постоянный указатель на константу int» .

Edit: Для Dos и Don'ts, если этого ответа недостаточно, не могли бы вы уточнить, что хотите?




В C ++ есть много других тонких точек, окружающих константную корректность. Я предполагаю, что вопрос здесь просто о C, но я приведу некоторые связанные примеры, поскольку тег - это C ++:

  • Вы часто передаете большие аргументы, такие как строки, как TYPE const & которые не позволяют объекту либо модифицироваться, либо копироваться. Пример :

    TYPE& TYPE::operator=(const TYPE &rhs) { ... return *this; }

    Но TYPE & const имеет смысла, поскольку ссылки всегда const.

  • Вы всегда должны указывать методы класса, которые не изменяют класс как const , иначе вы не можете вызвать метод из TYPE const & ссылки. Пример :

    bool TYPE::operator==(const TYPE &rhs) const { ... }

  • Существуют общие ситуации, когда как возвращаемое значение, так и метод должны быть const. Пример :

    const TYPE TYPE::operator+(const TYPE &rhs) const { ... }

    На самом деле, методы const не должны возвращать внутренние данные класса как ссылку на не-const.

  • В результате часто приходится создавать как const, так и неконстантный метод с использованием перегрузки const. Например, если вы определяете T const& operator[] (unsigned i) const; , то вам, вероятно, также захочется неконстантная версия, заданная:

    inline T& operator[] (unsigned i) { return const_cast<char&>( static_cast<const TYPE&>(*this)[](i) ); }

Afaik, в C нет функций const, функции нечлена не могут быть const в C ++, методы const могут иметь побочные эффекты, а компилятор не может использовать функции const, чтобы избежать дублирования вызовов функций. На самом деле даже простой int const & reference может свидетельствовать о том, что значение, к которому оно относится, должно быть изменено в другом месте.




Этот вопрос точно показывает, почему мне нравится делать то, о чем я упомянул в своем вопросе, является константа после допустимого типа id?

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

Если кто-то решает поставить его на передний план (например: «const int *»), в качестве особого исключения в этом случае он применяется к предмету после него.

Многие люди любят использовать это специальное исключение, потому что считают, что это выглядит лучше. Мне это не нравится, потому что это исключение и, таким образом, путает вещи.




Синтаксис объявления C и C ++ неоднократно описывался как неудачный эксперимент, оригинальные дизайнеры.

Вместо этого давайте назовем тип «указатель на Type »; Я назову это Ptr_ :

template< class Type >
using Ptr_ = Type*;

Теперь Ptr_<char> является указателем на char .

Ptr_<const char> является указателем на const char .

И const Ptr_<const char> является const Ptr_<const char> указателем на const char .

Там.




Links