Выбрать главу

int myabs(int i)

{

 cout << "Использование int-функции myabs(): ";

 if(i<0) return -i;

 else return i;

}

double myabs(double d)

{

 cout << "Использование double-функции myabs(): ";

 if(d<0.0) return -d;

 else return d;

}

long myabs(long l)

{

 cout << "Использование long-функции myabs(): ";

 if(1<0) return -1;

 else return 1;

}

Результаты выполнения этой программы таковы.

Использование int-функции myabs(): 10

Использование double-функции myabs(): 11

Использование long-функции myabs(): 9

При выполнении эта программа создает три похожие, но все же различные функции, вызываемые с использованием "общего" (одного на всех) имени myabs. Каждая из них возвращает абсолютное значение своего аргумента. Во всех ситуациях вызова компилятор "знает", какую именно функцию ему использовать. Для принятия решения ему достаточно "взглянуть" на тип аргумента, передаваемого функции. Принципиальная значимость перегрузки состоит в том, что она позволяет обращаться к связанным функциям посредством одного, общего для всех, имени. Следовательно, имя myabs представляет общее действие, которое выполняется во всех случаях. Компилятору остается правильно выбрать конкретную версию при конкретных обстоятельствах. Благодаря полиморфизму программисту нужно помнить не три различных имени, а только одно. Несмотря на простоту приведенного примера, он позволяет понять, насколько перегрузка способна упростить процесс программирования.

Каждая версия перегруженной функции может выполнять любые действия. Другими словами, не существует правила, которое бы обязывало программиста связывать перегруженные функции общими действиями. Однако с точки зрения стилистики перегрузка функций все-таки подразумевает определенное "родство" его версий. Таким образом, несмотря на то, что одно и то же имя можно использовать для перегрузки не связанных общими действиями функций, этого делать не стоит. Например, в принципе можно использовать имя sqr для создания функции, которая возвращает квадрат целого числа, и функции, которая возвращает значение квадратного корня из вещественного числа (типа double). Но, поскольку эти операции фундаментально различны, применение механизма перегрузки методов в этом случае сводит на нет его первоначальную цель. (Такой стиль программирования, наверное, подошел бы лишь для того, чтобы ввести в заблуждение конкурента.) На практике перегружать имеет смысл только тесно связанные операции.

Анахронизм в виде ключевого слова overload

На заре создания C++ перегруженные функции необходимо было явным образом объявлять таковыми с помощью ключевого слова overload. Это ключевое слово больше не требуется в C++. В действительности стандартом C++ оно даже не включено в список ключевых слов. Однако время от времени его можно встретить в каком-нибудь С++-коде, особенно в старых книгах и статьях.

Общая форма использования ключевого слова overload такова.

overload func_name;

Здесь элемент func_name представляет собой имя перегружаемой функции. Эта инструкция должна предшествовать объявлениям перегруженных функций. (В общем случае оно встречается в начале программы.) Например, если функция Counter() является перегруженной, то в программу могла быть включена такая строка.

overload Counter;

Если вы встретите overload-объявления при работе со старыми программами, их можно просто удалить: они больше не нужны. Поскольку ключевое слово overload — анахронизм, его не следует использовать в новых С++-программах. На самом деле большинство компиляторов его попросту не воспримет.

Аргументы, передаваемые функции по умолчанию 

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

Задание аргументов, передаваемых функции по умолчанию, синтаксически аналогично инициализации переменных. Рассмотрим следующий пример, в котором объявляется функция myfunc(), принимающая один аргумент типа double с действующим по умолчанию значением 0.0 и один символьный аргумент с действующим по умолчанию значением 'Х'.