Могу ли я опустить квалификаторы const в объявлении для типов указателей? - PullRequest
2 голосов
/ 12 ноября 2011

Для определения функции, которое содержит объявление типа void foo(const int ) Действительны оба следующих объявления.

void foo(const int); // valid
void foo(int); // valid, const can be omitted.

Но если определение функции содержит объявление типа void foo(const int*), пропуск const недопустим:

void foo(const int *); // valid declaration
void foo(int *); // error: const cannot be omitted.

Почему const нельзя опускать в объявлении функции, если ее параметр имеет типы указателей? В чем разница?

Ответы [ 3 ]

3 голосов
/ 12 ноября 2011

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

void foo(int* const);
void foo(int*);
3 голосов
/ 12 ноября 2011

const int x означает, что x только для чтения внутри функции. Внешнему миру все равно; функция работает с копией аргумента.

Однако const int *p означает, что p указывает на то, что доступно только для чтения. Внешний мир заботится об этом; это обещание, что pointee не может быть изменен.

Следствием этого является то, что следующие два объявления эквивалентны:

void foo(const int *);
void foo(const int * const);
2 голосов
/ 12 ноября 2011

Функция имеет дело с копией переданного аргумента.Если это целое число, вы можете опустить const, так как оригинал не будет затронут в любом случае.В случае указателя на тип int есть три варианта:

  1. int* p
  2. const int* p (или int const* p)
  3. const int* const p (или int const* const p)

const может применяться к указанному объекту, самому указателю или к обоим.В качестве аргумента вы передаете указатель, поэтому вы можете опустить const для него, так как его копия передается в функцию.Таким образом, (2) и (3) могут использоваться взаимозаменяемо (только при использовании в качестве типа аргумента функции!).Но const для типа заостренного объекта имеет значение:

  • void foo(const int* p); // функция не может изменить указанный целочисленный объект через p
  • void foo(int* p); // функция может изменить указанный целочисленный объектчерез p

В обоих случаях функция может изменять p внутри функции, но эти изменения не отражаются на исходном значении указателя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...