Значение по умолчанию параметра функции


1.

int Add (int a, int b = 3);
int Add (int a, int b)
{

}

2.

int Add (int a, int b);
int Add (int a, int b = 3)
{

}

обе работы, что является стандартным способом почему?

4 109

4 ответа:

если вы поместите объявление в заголовочный файл, а определение в отдельный и #include заголовок из другой .cpp файл, вы сможете увидеть разницу.

в частности, предположим, что:

lib.h

int Add(int a, int b);

lib.cpp

int Add(int a, int b = 3) {
   ...
}

в C++ требования, предъявляемые к аргументам по умолчанию в отношении их расположения в списке параметров, следующие:

  1. аргумент по умолчанию для данного параметра должен быть указан не более одного раза. Указание его более одного раза (даже с тем же значением по умолчанию) является незаконным.

  2. параметры с аргументами по умолчанию должны сформировать непрерывную группу в конце списка параметров.

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

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

void foo(int a, int b);

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

позже (далее вниз) в той же единице перевода, вы можете повторно объявить его снова, но на этот раз с одним аргументом по умолчанию

void foo(int a, int b = 5);

и с этого момента вы можете вызвать его только с одним явным аргументом.

Далее вы можете повторно заявить его еще раз, добавив еще один аргумент по умолчанию

void foo(int a = 1, int b);

и с этого момента вы можете называть его без явных аргументов.

полный пример может выглядеть следующим образом

void foo(int a, int b);

int main()
{
  foo(2, 3);

  void foo(int a, int b = 5); // redeclare
  foo(8); // OK, calls `foo(8, 5)`

  void foo(int a = 1, int b); // redeclare again
  foo(); // OK, calls `foo(1, 5)`
}

void foo(int a, int b)
{
  // ...
}

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

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

аргументы по умолчанию должны быть указаны с первым вхождением имени функции-как правило, в прототипе функции. Если прототип функции опущен, поскольку определение функции также служит прототипом, то в заголовке функции должны быть указаны аргументы по умолчанию.

первый способ был бы предпочтительнее второго.

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

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