Значения параметров по умолчанию
Значение параметра по умолчанию– это значение, которое разработчик считает подходящим в большинстве случаев употребления функции, хотя и не во всех. Оно освобождает программиста от необходимости уделять внимание каждой детали интерфейса функции.
Значения по умолчанию для одного или нескольких параметров функции задаются с помощью того же синтаксиса, который употребляется при инициализации переменных. Например, функция для создания и инициализации двумерного массива, моделирующего экран терминала, может использовать такие значения для высоты, ширины и символа фона экрана:
char *screenInit( int height = 24, int width = 80,
char background = ' ' );
Функция, для которой задано значение параметра по умолчанию, может вызываться по-разному. Если аргумент опущен, используется значение по умолчанию, в противном случае – значение переданного аргумента. Все следующие вызовы screenInit() корректны:
char *cursor;
// эквивалентно screenInit(24,80,' ')
cursor = screenInit();
// эквивалентно screenInit(66,80,' ')
cursor = screenlnit(66);
// эквивалентно screenInit(66,256,' ')
cursor = screenlnit(66, 256);
cursor = screenlnit(66, 256, '#');
Фактические аргументы сопоставляются с формальными параметрами позиционно (в порядке следования), и значения по умолчанию могут использоваться только для подстановки вместо отсутствующих последних аргументов. В нашем примере невозможно задать значение для background, не задавая его для height и width.
// эквивалентно screenInit('?',80,' ')
cursor = screenInit('?');
// ошибка, неэквивалентно screenInit(24,80,'?')
cursor = screenInit( , ,'?');
При разработке функции с параметрами по умолчанию придется позаботиться об их расположении. Те, для которых значения по умолчанию вряд ли будут употребляться, необходимо поместить в начало списка. Функция screenInit() предполагает (возможно, основываясь на опыте применения), что параметр height будет востребован пользователем наиболее часто.
Значения по умолчанию могут задаваться для всех параметров или только для некоторых. При этом параметры без таких значений должны идти раньше тех, для которых они указаны.
// ошибка: width должна иметь значение по умолчанию,
// если такое значение имеет height
char *screenlnit( int height = 24, int width,
char background = ' ' );
Значение по умолчанию может указываться только один раз в файле. Следующая запись ошибочна:
// tf.h
int ff( int = 0 );
// ft.С
#include "ff.h"
int ff( int i = 0) { ... } // ошибка
По соглашению значение задается в объявлении функции, которое размещается в общедоступном заголовочном файле (описывающем интерфейс), а не в ее определении. Если же указать его в определении, это значение будет доступно только для вызовов функции внутри исходного файла, содержащего это определение.
Можно объявить функцию повторно и таким образом задать дополнительные параметры по умолчанию. Это удобно при настройке универсальной функции для конкретного приложения. Скажем, в системной библиотеке UNIX есть функция chmod(), изменяющая режим доступа к файлу. Ее объявление содержится в системном заголовочном файле <cstdlib>:
int chmod( char *filePath, int protMode );
protMode представляет собой режим доступа, а filePath – имя и каталог файла. Если в некотором приложении файл только читается, можно переобъявить функцию chmod(), задав для соответствующего параметра значение по умолчанию, чтобы не указывать его при каждом вызове:
#include <cstdlib>
int chmod( char *filePath, int protMode=0444 );
Если функция объявлена в заголовочном файле так:
file int ff( int a, int b, int с = 0 ); // ff.h
то как переобъявить ее, чтобы присвоить значение по умолчанию для параметра b? Следующая строка ошибочна, поскольку она повторно задает значение для с:
#include "ff.h"
int ff( int a, int b = 0, int с = 0 ); // ошибка
Так выглядит правильное объявление:
#include "ff.h"
int ff( int a, int b = 0, int с ); // правильно
В том месте, где мы переобъявляем функцию ff(), параметр b расположен правее других, не имеющих значения по умолчанию. Поэтому требование присваивать такие значения справа налево не нарушается. Теперь мы можем переобъявить ff() еще раз:
#include "ff.h"
int ff( int a, int b = 0, int с ); // правильно
int ff( int a = 0, int b, int с ); // правильно
Значение по умолчанию не обязано быть константным выражением, можно использовать любое:
int aDefault();
int bDefault( int );
int cDefault( double = 7.8 );
int glob;
int ff( int a = aDefault() ,
int b = bDefau1t( glob ) ,
int с = cDefault() );
Если такое значение является выражением, то оно вычисляется во время вызова функции. В примере выше cDefault() работает каждый раз, когда происходит вызов функции ff() без указания третьего аргумента.