Язык C++ позволяет присваивать параметрам функции значения по умолчанию в том случае, когда при вызове функции не указываются параметры. Значения по умолчанию задаются синтаксически сходным образом с инициализацией переменных. Например, ниже объявляется функция f(), имеющая аргументом целую переменную, значением которой по умолчанию является величина 1:
void f(int i = 1);
Теперь функция f() может вызываться двумя способами, как показано ниже:
f(10); // явная передача значения
f(); // функция использует значение по умолчанию
В первом случае аргументу i будет присвоено значение 10. Во втором случае i получит значение по умолчанию, равное 1.
Аргументы по умолчанию в языке C++ позволяют программисту писать более простой код. Для того, чтобы охватывать множество ситуаций, часто функция содержит больше параметров, чем это необходимо при ее наиболее типичном использовании. Используя аргументы по умолчанию, можно указать только аргументы, которые отличаются от значений по умолчанию в каждой конкретной ситуации.
Чтобы лучше представить себе причины использования аргументов по умолчанию, рассмотрим функцию, преобразующая целое число в строку:
char* int_to_string(char *string, int value=999, int base=10)
{
return _itoa(value, string, base);
}
Здесь value – преобразовываемое число, string – буфер для получаемой строки, а base – система счисления, в которой будет представлено число после преобразования в строку.
Следующая короткая программа демонстрирует использование функции int_to_string().
#include <iostream.h>
#include <stdlib.h>
void main()
{
char buffer[20];
cout << int_to_string(buffer, 12345, 16) << “ “; //число 12345 будет представлено в 16-ричной системе счисления
cout << int_to_string(buffer, 12345) << “ “; //число 12345 будет представлено в 10-чной системе счисления (по умолчанию)
cout << int_to_string(buffer) << “\n”; //по умолчанию используется 10-чная система счисления и число 999
return 0;
}
При необходимости использования системы счисления, отличной от десятичной, нужно указать ее явно. В случае использования десятичной системы счисления, ее можно не указывать. Также можно не указывать преобразовываемое число, хотя на практике от этого, скорее всего, не будет большой пользы.
Обратим внимание, что функция int_to_string() вызываются с тремя, двумя или одним аргументом. В случае вызова с одним аргументом величины value и base задаются по умолчанию. При вызове с двумя аргументами величина base задается по умолчанию. Однако невозможно вызвать функцию int_to_string() с величиной value, заданной по умолчанию, и величиной base, заданной при вызове функции. В общем случае при вызове функции ее аргументы совмещаются с соответствующими параметрами слева направо. После того, как всем использованным при вызове функции аргументам поставлены в соответствие параметры, оставшимся аргументам присваиваются их значения по умолчанию.
При создании функции, имеющей аргументы по умолчанию, их значения должны быть указаны только один раз, причем в тот самый момент, когда функция первый раз объявляется в файле. Например, если функция int_to_string() определена после функции main(), то аргументы по умолчанию должны объявляться в прототипе функции int_to_string(), но эти значения больше не должны повторяться при определении функции int_to_string().
Хотя аргументы по умолчанию не могут быть переопределены, при перегрузке функции каждая ее версия может включать в себя новые значения аргументов по умолчанию.
При определении параметров важно понимать, что все параметры по умолчанию располагаются правее параметров, которые не имеют значений по умолчанию. Это означает, что после того, как определен параметр, имеющий значение по умолчанию, нельзя ввести в интерфейсе функции параметр, не имеющий значения по умолчанию. Например, следующее объявление функции int_to_string() является некорректным:
// некорректно!
char* int_to_string(char *string, int value=999, int base);
После того как начались параметры по умолчанию, в списке не могут появиться параметры, не имеющие значения по умолчанию.
Также можно использовать параметры со значениями по умолчанию в конструкторе объекта. В качестве примера ниже приведена новая версия конструктора класса queue:
queue::queue(int id=0)
{
s = r = 0;
who = id;
cout << "Queue " << who << " initialized.\n";
}
В этой версии при объявлении объекта без инициализации каким-либо значением параметр id принимает значение по умолчанию, равное 0. Например, в результате объявления
queue a, b(2);
создаются два объекта - а и b. Значение id для объекта a равно 0, а для объекта b равно 2.