Важно понимать, что все параметры, которые принимают значения по умолчанию, должны быть расположены справа от остальных. Например, следующий прототип функции содержит ошибку.
// Неверно!
void f(int а = 1, int b);
Если вы начали определять параметры, которые принимают значения по умолчанию, нельзя после них указывать параметры, задаваемые при вызове функции только явным образом. Поэтому следующее объявление также неверно и не будет скомпилировано.
int myfunc(float f, char *str, int i=10, int j);
Поскольку для параметра i определено значение по умолчанию, для параметра j также нужно задать значение по умолчанию.
Как упоминалось в начале этого раздела, одним из применений передачи аргументов по умолчанию является "сокращенная форма" перегрузки функций. Чтобы понять это, представьте, что вам нужно создать две "адаптированные" версии стандартной функции strcat(). Одна версия должна присоединять все содержимое одной строки к концу другой. Вторая же принимает третий аргумент, который задает количество конкатенируемых (присоединяемых) символов. Другими словами, эта версия должна конкатенировать только заданное количество символов одной строки к концу другой.
Допустим, что вы назвали свои функции именем mystrcat() и предложили такой вариант их прототипов.
void mystrcat(char *s1, char *s2, int len);
void mystrcat(char *s1, char *s2);
Первая версия должна скопировать len символов из строки s2 в конец строки s1. Вторая версия копирует всю строку, адресуемую указателем s2, в конец строки, адресуемой указателем s1, т.е. действует подобно стандартной функции strcat().
Несмотря на то что для достижения поставленной цели можно реализовать две версии функции mystrcat(), есть более простой способ решения этой задачи. Используя возможность передачи аргументов по умолчанию, можно создать только одну функцию mystrcat(), которая заменит обе задуманные ее версии. Реализация этой идеи продемонстрирована в следующей программе.
// Применение пользовательской версии функции strcat().
#include <iostream>
#include <cstring>
using namespace std;
void mystrcat(char *s1, char *s2, int len = -1);
int main()
{
char str1[80] = "Это тест.";
char str2[80] = "0123456789";
mystrcat(str1, str2, 5); // Присоединяем 5 символов.
cout << str1 << '\n';
strcpy(str1, "Это тест."); // Восстанавливаем str1.
mystrcat(str1, str2); // Присоединяем всю строку.
cout << str1 << '\n';
return 0;
}
// Пользовательская версия функции strcat().
void mystrcat(char *s1, char *s2, int len)
{
// Находим конец строки s1.
while(*s1) s1++;
if(len == -1) len = strlen(s2);
while(*s2 && len) {
*s1 = *s2; // Копируем символы.
s1++; s2++; len--;
}
*s1 = '\0'; // Завершаем строку s1 нулевым символом.
}
Здесь функция mystrcat() присоединяет len символов строки, адресуемой параметром s2, к концу строки, адресуемой параметром s1. Но если значение len равно -1, как и в случае разрешения передачи этого аргумента по умолчанию, функция mystrcat() присоединит к строке s1 всю строку, адресуемую параметром s2. (Другими словами, если значение len равно -1, функция mystrcat() действует подобно стандартной функции strcat().) Используя для параметра len возможность передачи аргумента по умолчанию, обе операции можно объединить в одной функции.
Этот пример позволил продемонстрировать, как аргументы, передаваемые функции по умолчанию, обеспечивают основу для сокращенной формы объявления перегруженных функций.