8.12 – Аргументы по умолчанию
Аргумент по умолчанию – это значение по умолчанию, предоставленное для параметра функции. Если пользователь не предоставляет явный аргумент для параметра с аргументом по умолчанию, то будет использоваться значение по умолчанию. Если пользователь предоставляет аргумент для этого параметра, то используется аргумент, предоставленный пользователем.
Поскольку пользователь может выбрать, следует ли предоставить конкретное значение аргумента или использовать значение по умолчанию, параметр с предоставленным значением по умолчанию часто называется необязательным параметром.
Рассмотрим следующую программу:
// 10 - аргумент по умолчанию, y - теперь необязательный параметр
void printValues(int x, int y=10)
{
std::cout << "x: " << x << '\n';
std::cout << "y: " << y << '\n';
}
int main()
{
printValues(1); // y будет использовать аргумент по умолчанию 10
printValues(3, 4); // y будет использовать предоставленный
// пользователем аргумент 4
}
Эта программа создает следующий вывод:
x: 1
y: 10
x: 3
y: 4
В первом вызове функции вызывающий не предоставил аргумент для y
, поэтому функция использовала значение по умолчанию 10. Во втором вызове вызывающий предоставил значение для y
, поэтому было использовано значение, указанное пользователем.
Аргументы по умолчанию – отличный вариант, когда функции требуется значение, которое пользователь может захотеть или не захотеть переопределить. Например, вот несколько прототипов функций, для которых обычно могут использоваться аргументы по умолчанию:
void openLogFile(std::string filename="default.log");
int rollDie(int sides=6);
void printStringInColor(std::string str, Color color=COLOR_BLACK); // Color - это перечисление
Несколько аргументов по умолчанию
Функция может иметь несколько параметров с аргументами по умолчанию:
void printValues(int x=10, int y=20, int z=30)
{
std::cout << "Values: " << x << " " << y << " " << z << '\n';
}
Для следующих вызовов функции:
printValues(1, 2, 3);
printValues(1, 2);
printValues(1);
printValues();
Будет создан следующий вывод:
Values: 1 2 3
Values: 1 2 30
Values: 1 20 30
Values: 10 20 30
Обратите внимание, что невозможно предоставить аргумент для параметра z
без предоставления аргументов для параметров x
и y
. Это связано с тем, что C++ не поддерживает синтаксис вызова функции, такой как printValues(,,3)
. Это имеет два основных последствия:
- Все аргументы по умолчанию должны быть для крайних правых параметров. Запрещено следующее:
void printValue(int x=10, int y); // не допустимо
- Если существует более одного аргумента по умолчанию, крайний левый аргумент по умолчанию должен быть тем, который с наибольшей вероятностью будет явно установлен пользователем.
Аргументы по умолчанию могут быть объявлены только один раз
После объявления аргумент по умолчанию не может быть объявлен повторно. Это означает, что для функции с предварительным объявлением и определением функции аргумент по умолчанию может быть объявлен либо в предварительном объявлении, либо в определении функции, но не в обоих сразу.
void printValues(int x, int y=10);
void printValues(int x, int y=10) // ошибка: переопределение аргумента по умолчанию
{
std::cout << "x: " << x << '\n';
std::cout << "y: " << y << '\n';
}
Лучше всего объявлять аргумент по умолчанию в предварительном объявлении, а не в определении функции, поскольку предварительное объявление с большей вероятностью будет замечено другими файлами (особенно если оно находится в заголовочном файле).
foo.h:
#ifndef FOO_H
#define FOO_H
void printValues(int x, int y=10);
#endif
main.cpp:
#include "foo.h"
#include <iostream>
void printValues(int x, int y)
{
std::cout << "x: " << x << '\n';
std::cout << "y: " << y << '\n';
}
int main()
{
printValues(5);
return 0;
}
Обратите внимание, что в приведенном выше примере мы можем использовать аргумент по умолчанию для функции printValues()
, потому что main.cpp включает с #include
файл foo.h, в котором находится предварительное объявление, определяющее аргумент по умолчанию.
Правило
Если функция имеет предварительное объявление, поместите туда аргумент по умолчанию. В противном случае поместите его в определение функции.
Аргументы по умолчанию и перегрузка функций
Функции с аргументами по умолчанию могут быть перегружены. Например, разрешено следующее:
void print(std::string string);
void print(char ch=' ');
Если бы пользователь вызвал print()
, это разрешилось бы в print(' ')
, что напечатало бы пробел.
Однако важно отметить, что необязательные параметры НЕ учитываются в отношении параметров, которые делают функцию уникальной. Следовательно, следующее недопустимо:
void printValues(int x);
void printValues(int x, int y=20);
Если бы вызывающий вызывал printValues(10)
, компилятор не смог бы однозначно определить, хочет ли пользователь вызвать printValues(int)
или printValues(int, 20)
со значением по умолчанию.
Резюме
Аргументы по умолчанию предоставляют полезный механизм для указания параметров, для которых пользователю необязательно указывать значения. Они часто используются в C++, и вы часто будете встречать их в будущих уроках.